博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Socket 实现聊天功能
阅读量:6691 次
发布时间:2019-06-25

本文共 4627 字,大约阅读时间需要 15 分钟。

作者:jijs

链接:
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

需要提前了解知识点

使用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

转载于:https://www.cnblogs.com/ios9/p/7473096.html

你可能感兴趣的文章
Big Faceless Java Pdf报表生成器控件介绍
查看>>
hadoop kill mapreduce job
查看>>
XPE常见问题整理
查看>>
Vim编辑器详解
查看>>
sql 查询几个工作日之后的日期
查看>>
zeromq的使用:例子分析
查看>>
ubuntu16.04的启动栏更改和窗口特效关闭
查看>>
我的友情链接
查看>>
java --log4j
查看>>
Nginx之server指令
查看>>
用普通计算机假设基于liunx系统的NAS部署FineReport决策系统
查看>>
shell日常脚本
查看>>
从尾到头打印链表
查看>>
百度笔试题面试题集总
查看>>
Nginx 499 报错,tomcat大量超时
查看>>
马兴150809305 飞机
查看>>
MySQL主从复制之半同步模式
查看>>
docker web管理工具安装---shipyard中文版
查看>>
KEEPALIVED双机热备
查看>>
openssl升级1.0.2k及nginx1.14.0编译安装
查看>>