zoukankan      html  css  js  c++  java
  • Socket 实现聊天功能

    注:本文来自:简书: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 


    image

  • 相关阅读:
    第二次作业
    第一次软件测试
    activity带数据跳转
    学生注册界面
    activity_main
    购物商城
    2021.4.14JSP第七周作业
    2021.4.7jsp第六周作业
    2021.3.26JSP第四次作业
    2021/3/10 第二次JSP作业
  • 原文地址:https://www.cnblogs.com/ios9/p/7473096.html
Copyright © 2011-2022 走看看