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
为人:谦逊、激情、博学、审问、慎思、明辨、 笃行
学问:纸上得来终觉浅,绝知此事要躬行
为事:工欲善其事,必先利其器。
态度:道阻且长,行则将至;行而不辍,未来可期
.....................................................................
------- 桃之夭夭,灼灼其华。之子于归,宜其室家。 ---------------
------- 桃之夭夭,有蕡其实。之子于归,宜其家室。 ---------------
------- 桃之夭夭,其叶蓁蓁。之子于归,宜其家人。 ---------------
=====================================================================
* 博客文章部分截图及内容来自于学习的书本及相应培训课程以及网络其他博客,仅做学习讨论之用,不做商业用途。
* 如有侵权,马上联系我,我立马删除对应链接。 * @author Alan -liu * @Email no008@foxmail.com
转载请标注出处! ✧*꧁一品堂.技术学习笔记꧂*✧. ---> https://www.cnblogs.com/ios9/
学问:纸上得来终觉浅,绝知此事要躬行
为事:工欲善其事,必先利其器。
态度:道阻且长,行则将至;行而不辍,未来可期
.....................................................................
------- 桃之夭夭,灼灼其华。之子于归,宜其室家。 ---------------
------- 桃之夭夭,有蕡其实。之子于归,宜其家室。 ---------------
------- 桃之夭夭,其叶蓁蓁。之子于归,宜其家人。 ---------------
=====================================================================
* 博客文章部分截图及内容来自于学习的书本及相应培训课程以及网络其他博客,仅做学习讨论之用,不做商业用途。
* 如有侵权,马上联系我,我立马删除对应链接。 * @author Alan -liu * @Email no008@foxmail.com
转载请标注出处! ✧*꧁一品堂.技术学习笔记꧂*✧. ---> https://www.cnblogs.com/ios9/