Socket 实现聊天功能
Posted ✧*꧁一品堂.技术学习笔记꧂*✧.
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Socket 实现聊天功能相关的知识,希望对你有一定的参考价值。
作者: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
以上是关于Socket 实现聊天功能的主要内容,如果未能解决你的问题,请参考以下文章
从0实现基于Linux socket聊天室-增加数据加密功能-6
从0实现基于Linux socket聊天室-实现聊天室的登录注册功能-3