简单的socket粘包,半包处理

package socket;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class MsgServer {
    // 缓存一个read事件中一个不完整的包,以待下次read事件到来时拼接成完整的包
    StringBuilder StringCacheBuffer = new StringBuilder();
    boolean cache = false;

    public static void main(String[] args) {
        try {
            MsgServer server = new MsgServer();
            server.setUpServer(9292);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void setUpServer(int port) throws IOException {
        ServerSocket server = new ServerSocket(port);
        while (true) {
            Socket client = server.accept();
            System.out.println("客户端IP:" + client.getRemoteSocketAddress());
            processMesage(client);
        }
    }

    private void processMesage(Socket client) throws IOException {
        InputStream ins = client.getInputStream();
        DataInputStream dins = new DataInputStream(ins);
        int bodyLen = -1;
        // 服务端解包过程
        byte[] data = new byte[10];
        byte[] cacheBuffer = null;
        byte flag = dins.readByte();
        int totalLen = dins.readInt();
        // 读取第一次获得的包消息长度
        //try{
        int count=0;
        bodyLen = totalLen - 5;
        System.out.println("消息总长度" + bodyLen);
        try{
        while (true) {
            // 还没有读出包头,先读出包头
            if (bodyLen == -1) {
                if (bodyLen > data.length) {
                    cache = true;
                } else {
                    data = new byte[bodyLen];
                    dins.readFully(data);
                    String msgs = new String(data);
                    System.out.println("发来的内容是1:" +StringCacheBuffer.toString()+msgs);
                }
            } else {
                if (data.length >= bodyLen) {
                    byte[] datas = new byte[bodyLen];
                    dins.readFully(datas);
                    String msgs = new String(datas);
                    System.out.println("发来的内容是2:" +StringCacheBuffer.toString()+msgs);
                } else {
                    cache = true;
                }
            }
            if (cache) {
                cacheBuffer = new byte[10];
                dins.readFully(cacheBuffer);
                StringCacheBuffer.append(new String(cacheBuffer));
                count=count+10;
            }
            if(bodyLen-count<=data.length){
                bodyLen=bodyLen-count;
            }
        }
        }catch(Exception e){
            e.printStackTrace();
        }
        StringCacheBuffer=new StringBuilder();
    }
}
代码还需要优化。主要学习自定义协议,以及解决粘包半包问题。

协议:包类型(1个byte)+包长度(1个int)+消息长度

猜你喜欢

转载自my.oschina.net/u/3077789/blog/1806369