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
原文地址:https://www.cnblogs.com/snail-lb/p/5597623.html