• java 网络编程


    一、TCP实现小型聊天室

    实现方法:服务器端接受所有的消息,然后把接收到的每一条消息发送给所有已连接的设备上去。

    服务器端代码:

     1 package com.TCP;
     2 
     3 import java.util.*;
     4 
     5 
     6 import java.net.*;
     7 import java.io.*;
     8 public class TCPServer_2 {
     9     
    10     private int no = 0; //为连接设备编号
    11 
    12     // 保存当前连接的客户端Socket
    13     private List<Socket> sockList = Collections.synchronizedList(new ArrayList<Socket>());
    14 
    15     class ServerThread implements Runnable {
    16         int no;
    17         Socket s;
    18         BufferedReader br;
    19 
    20         public ServerThread(Socket s, int no) {
    21             this.s = s;
    22             this.no = no;
    23             try {
    24                 br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    25             } catch (IOException e) {
    26                 e.printStackTrace();
    27             }
    28         }
    29 
    30         private String getContentByLine() {
    31             try {
    32                 return br.readLine();
    33             } catch (IOException e) { // 该请求可能已被客户端关闭
    34                 e.printStackTrace();
    35                 sockList.remove(s); // 因此需要从列表中移除
    36             }
    37             return null;
    38         }
    39 
    40         @Override
    41         public void run() {
    42             String content = "";
    43             while ((content = getContentByLine()) != null) {
    44             // 只要客户端不关闭Socket,那么输入输出流就是一直开着的
    45             // 服务器端会一直等待输入,永远也到不了EOF使getContentByLine返回null
    46                 for (Socket s: sockList) { // 对每一个连接的客户端都发送聊天信息
    47                     PrintStream ps;
    48                     try {
    49 //                        ps = new PrintStream(s.getOutputStream());
    50 //                        ps.println("#" + no + " says: " + content);
    51 //                        ps.println(x);
    52                         DataOutputStream dataOut = new DataOutputStream(s.getOutputStream());
    53                         if("CI".equals(content.substring(0, 2))){
    54                             dataOut.writeBytes("SCXX" + '
    ');
    55                         }
    56                         else if("CS".equals(content.substring(0, 2))){
    57                             dataOut.writeBytes("SLXX" + '
    ');
    58                         }else{
    59                             dataOut.writeBytes("#" + no + " says: " + content);
    60                         }
    61                     } catch (IOException e) {
    62                         // TODO Auto-generated catch block
    63                         e.printStackTrace();
    64                     }
    65                 }
    66             }
    67         }
    68 
    69     }
    70     
    71     public void init() throws IOException {
    72 //        ServerSocket ss = new ServerSocket(8000, 10, InetAddress.getByName("192.168.96.1")); // 使用默认IP,端口3000
    73         ServerSocket ss = new ServerSocket(8000);
    74         while (true) {
    75             Socket s = ss.accept();
    76             no += 1;
    77             System.out.println("#" + no + " connected!");
    78             sockList.add(s);
    79             new Thread(new ServerThread(s, no)).start();
    80         }
    81     }
    82 
    83     public static void main(String[] args) throws IOException {
    84         new TCPServer_2().init();
    85     }
    86 
    87 }
    View Code

    客户端代码:

     1 package com.TCP;
     2 
     3 import java.util.*;
     4 import java.net.*;
     5 import java.io.*;
     6 public class TCPClient_2 {
     7     
     8 
     9     class ClientThread implements Runnable {
    10         private Socket s;
    11 
    12         public ClientThread(Socket s) {
    13             this.s = s;
    14         }
    15 
    16         @Override
    17         public void run() {
    18             try {
    19                 String content = "";
    20                 BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    21                 while ((content = br.readLine()) != null) { // 不断读取服务器发来的广播消息
    22                     System.out.println(content);
    23                 }
    24             } catch (Exception e) {
    25                 e.printStackTrace();
    26             }
    27         }
    28     }
    29 
    30     public void init() throws UnknownHostException, IOException {
    31         Socket s = new Socket("192.168.1.106", 8000);
    32         new Thread(new ClientThread(s)).start(); // 建立连接后马上监控广播消息
    33 
    34         PrintStream ps = new PrintStream(s.getOutputStream()); // 输出流定向到远程
    35         
    36         String line = "";
    37         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    38         while ((line = br.readLine()) != null) { // 从控制台键盘读取输入
    39             ps.println(line); // 发送到远程
    40         }
    41     }
    42 
    43     public static void main(String[] args) throws UnknownHostException, IOException {
    44         new TCPClient_2().init();
    45     }
    46 
    47 }
    View Code

    二、UDP实现组播播消息(UDP没有c/s概念,所以多开几个程序就能相互通信了)

     1 package com.UDP_Port;
     2 
     3 import java.io.IOException;
     4 import java.net.DatagramPacket;
     5 import java.net.InetAddress;
     6 import java.net.MulticastSocket;
     7 import java.util.Scanner;
     8 
     9 public class UDPMulticast {
    10 
    11     private final static String BC_IP = "230.0.0.1"; // 组播地址
    12     private final static int BC_PORT = 30000; // 组播端口
    13     private final static int PACK_SIZE = 4096;
    14 
    15     public void init() throws IOException {
    16         MulticastSocket sock = new MulticastSocket(BC_PORT);
    17         InetAddress bcAddr = InetAddress.getByName(BC_IP);
    18         try (Scanner scan = new Scanner(System.in)) {
    19             // 创建socket并加入组播地址
    20             sock.joinGroup(bcAddr);
    21             sock.setLoopbackMode(false); // 必须是false才能开启广播功能!!
    22 
    23             new Thread(() -> { // 接受广播消息的线程
    24                 try {
    25                     DatagramPacket inpack = new DatagramPacket(new byte[PACK_SIZE], PACK_SIZE);
    26                     while (true) {
    27                         sock.receive(inpack);
    28                         System.out.println("广播消息:" + new String(inpack.getData(), 0, inpack.getLength()));
    29                     }
    30                 } catch (IOException e) {
    31                     e.printStackTrace();
    32                     if (sock != null) {
    33                         try {
    34                             sock.leaveGroup(bcAddr);
    35                         } catch (Exception e1) {
    36                             // TODO Auto-generated catch block
    37                             e1.printStackTrace();
    38                         }
    39                         sock.close();
    40                     }
    41                     System.exit(1);
    42                 }
    43             }).start();
    44 
    45             // 主线程接受控制台输入并广播出去
    46             DatagramPacket outpack = new DatagramPacket(new byte[0], 0, bcAddr, BC_PORT); // 目的端口和MulticastSocket端口一样!!
    47             while (scan.hasNextLine()) {
    48                 byte[] buf = scan.nextLine().getBytes();
    49                 outpack.setData(buf);
    50                 sock.send(outpack);
    51             }
    52         } finally { // 最终关闭程序之前一定要关闭socket
    53             sock.close();
    54         }
    55     }
    56 
    57     public static void main(String[] args) throws NumberFormatException, IOException {
    58         // TODO Auto-generated method stub
    59         new UDPMulticast().init();
    60     }
    61 
    62 }
    View Code
  • 相关阅读:
    如何用redis/memcache做Mysql缓存层?
    孤儿进程和僵尸进程总结
    二叉树的遍历(非递归)
    Linux进程分配内存的两种方式--brk() 和mmap()
    Hbase
    cgroup 分析之CPU和内存部分
    十道海量数据处理面试题与十个方法大总结
    快速定位性能瓶颈,检查出所有资源(CPU、内存、磁盘IO等)的利用率(utilization)、饱和度(saturation)和错误(error)度量,即USE方法
    红黑树
    tcp 两个重要窗口:滑动窗口 和 拥塞窗口
  • 原文地址:https://www.cnblogs.com/snail-lb/p/5597623.html
Copyright © 2020-2023  润新知