您的位置:首页 > 其它

Socket 实现聊天功能

2017-09-04 12:53 225 查看
注:本文来自:简书:jianshu作者:jijs
链接:http://www.jianshu.com/p/7c0722a8b66f
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
需要提前了解知识点
java.net.Socket 解析
java.net.ServerSocket 解析使用socket实现一个端对端聊天系统。消息的格式为:消息长度(int)+消息内容通过消息长度来进行socket分包,防止读取出现半包、粘包等问题。

服务端代码

1 import java.io.IOException;
2 import java.io.InputStream;
3 import java.io.OutputStream;
4 import java.net.ServerSocket;
5 import java.net.Socket;
6
7 /**
8  * @author jijs
9  * @date 2017-08-14
10  */
11 public class ChatServer {
12     public static void main(String[] args) throws Exception {
13         start();
14     }
15
16     public static void start() throws Exception {
17         try (ServerSocket ss = new ServerSocket(9000);
18                 Socket s = ss.accept();
19                 InputStream is = s.getInputStream();
20                 OutputStream os = s.getOutputStream();) {
21
22             //开启一个线程,实时读取对方发过来的消息
23             new Thread(ChatUtil.receive(is)).start();
24
25             //从控制台输入消息,并发送
26             ChatUtil.send(os);
27
28         } catch (IOException e) {
29             e.printStackTrace();
30         }
31
32     }
33
34 }

客户端代码


1 import java.io.IOException;
2 import java.io.InputStream;
3 import java.io.OutputStream;
4 import java.net.Socket;
5
6 /**
7  * @author jijs
8  * @date 2017-08-14
9  */
10 public class ChatClient {
11
12     public static void main(String[] args) throws Exception {
13         start();
14     }
15
16     public static void start() {
17         try (Socket s = new Socket("127.0.0.1", 9000);
18                 InputStream is = s.getInputStream();
19                 OutputStream os = s.getOutputStream();) {
20
21             //开启一个线程,实时读取对方发过来的消息
22             new Thread(ChatUtil.receive(is)).start();
23
24             //从控制台输入消息,并发送
25             ChatUtil.send(os);
26
27         } catch (IOException e) {
28             e.printStackTrace();
29         }
30
31     }
32
33 }

聊天工具类

1 import java.io.IOException;
2 import java.io.InputStream;
3 import java.io.OutputStream;
4 import java.util.Scanner;
5
6 /**
7  * @author jijs
8  * @date 2017-08-14
9  */
10 public class ChatUtil {
11
12     /**
13      * 读取对方发过来的消息
14      * @param is
15      * @return
16      */
17     public static Runnable receive(final InputStream is) {
18         return new Runnable() {
19             public void run() {
20                 while (true) {
21                     try {
22                         // 当前消息总字节长度
23                         int returnLen = ChatUtil.readLen(is);
24                         byte[] b = new byte[returnLen];
25                         int readSize = 0; // 每次读取的字节数
26                         int count = 0; // 总读取的字节数
27                         while (count < returnLen && (readSize = is.read(b)) != -1) {
28                             count += readSize;
29                         }
30                         String str = new String(b, 0, readSize);
31                         System.out.println("接收:" + str);
32                     } catch (IOException e) {
33                         e.printStackTrace();
34                         break;
35                     }
36                 }
37             }
38         };
39     }
40
41     /**
42      * 从控制台接收用户输入,发送消息给对方
43      * @param os
44      */
45     public static void send(final OutputStream os) {
46         Scanner scan = new Scanner(System.in);
47         while (true) {
48             try {
49                 String s = scan.nextLine();
50                 byte[] data = s.getBytes();
51                 int len = data.length;
52                 os.write(ChatUtil.int2byte(len));
53                 os.write(data);
54                 os.flush();
55             } catch (IOException e) {
56                 e.printStackTrace();
57                 break;
58             }
59         }
60         scan.close();
61     }
62
63     /**
64      * 读取消息长度
65      * 消息格式为:消息长度+消息内容
66      * @param is
67      * @return
68      * @throws IOException
69      */
70     public static int readLen(InputStream is) throws IOException {
71         int b1 = is.read();
72         int b2 = is.read();
73         int b3 = is.read();
74         int b4 = is.read();
75         int len = (b1 << 24) + (b2 << 16) + (b3 << 8) + b4;
76         return len;
77     }
78
79     /**
80      * int 转 byte[] 数组
81      * @param len
82      * @return
83      */
84     public static byte[] int2byte(int len) {
85         byte[] b = new byte[4];
86         b[0] = (byte) (len >> 24);
87         b[1] = (byte) (len >> 16 & 0XFF);
88         b[2] = (byte) (len >> 8 & 0XFF);
89         b[3] = (byte) (len & 0XFF);
90         return b;
91     }
92 }
93

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: