java中处理socket通信过程中粘包的情况

时间:2022-09-03 00:14:09

这两天学习了java中处理socket通信过程中粘包的情况,而且很重要,所以,今天添加一点小笔记。

处理粘包程序是客户端的接受消息线程:

客户端:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.net.Socket;
import java.nio.CharBuffer;
 
public class TestSocketClient {
 
   
  public static void main(String[] args) {
    // TODO Auto-generated method stub
     
    new TestSocketClient().start();
  }
  class SendThread extends Thread{
    private Socket socket;
    public SendThread(Socket socket){
      this.socket=socket;
    }
    @Override
    public void run(){
      while(true){
        try{
          Thread.sleep(1000); 
          String send="<SOAP-ENV:Envelope>"+System.currentTimeMillis()+"</SOAP-ENV:Envelope>";
          PrintWriter pw=new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
          pw.write(send);
          pw.flush();
        }catch(Exception e){
          e.printStackTrace();
        }
      }
    }
  }
  class ReceiveThread extends Thread{
    private Socket socket;
    private volatile byte[] bytes=new byte[0];
    public ReceiveThread(Socket socket){
      this.socket=socket;
    }
    public byte[] mergebyte(byte[] a,byte[] b,int begin,int end){
      byte[] add=new byte[a.length+end-begin];
      int i=0;
      for(i=0;i<a.length;i++){
        add[i]=a[i];
      }
      for(int k=begin;k<end;k++,i++){
        add[i]=b[k];
      }
      return add;
    }
    @Override
    public void run(){
      while(true){
        try{
          InputStream reader=socket.getInputStream();
          if(bytes.length<2){
            byte[] head=new byte[2-bytes.length];
            int couter=reader.read(head);
            if(couter<0){
              continue;
            }
            bytes=mergebyte(bytes,head,0,couter);
            if(couter<2){
              continue;
            }
          }
          //下面这个值请注意,一定要取2长度的字节子数组作为报文长度,你懂得
          byte[] temp=new byte[0];
          temp=mergebyte(temp,bytes,0,2);
          String templength=new String(temp);
          int bodylength=Integer.parseInt(templength);      
          if(bytes.length-2<bodylength){
            byte[] body=new byte[bodylength+2-bytes.length];
            int couter=reader.read(body);
            if(couter<0){
              continue;
            }
            bytes=mergebyte(bytes,body,0,couter);
            if(couter<body.length){
              continue;
            }
          }
          byte[] body=new byte[0];
          body=mergebyte(body, bytes, 2, bytes.length);
          System.out.println("client receive body:  "+new String(body));
          bytes=new byte[0];
        }catch(Exception e){
          e.printStackTrace();
        }
      }
    }
  }
  public void start(){
    try{
    Socket socket=new Socket("127.0.0.1",18889);
    new SendThread(socket).start();
    new ReceiveThread(socket).start();
    }catch(Exception e){
      e.printStackTrace();
    }
     
  }
}

服务端:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package com.meituan.service.bankgate.gateway;
 
/**
 * Created by cqx on 16/7/19.
 */
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.CharBuffer;
import java.util.Date;
 
public class TESTAHAHHA {
 
  private final static String SOAP_BEGIN = "<SOAP-ENV:Envelope";
  private final static String SOAP_END = "</SOAP-ENV:Envelope>";
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    TESTAHAHHA testserver=new TESTAHAHHA();
    testserver.start();
  }
  public void start(){
    try{
      ServerSocket serversocket=new ServerSocket(18889);
      while(true){
        Socket socket=serversocket.accept();
        new SocketThread(socket).start();
      }
    }catch(Exception e){
      e.printStackTrace();
    }
 
  }
  class SocketThread extends Thread{
    private Socket socket;
    private String temp;
    public SocketThread(Socket socket){
      this.socket=socket;
    }
    public Socket getsocket(){
      return this.socket;
    }
    public void setsocjet(Socket socket){
      this.socket=socket;
    }
 
    @Override
    public void run(){
      try{
        Reader reader=new InputStreamReader(socket.getInputStream());
        // Writer writer=new PrintWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"));
        OutputStream writer=socket.getOutputStream();
        CharBuffer charbuffer=CharBuffer.allocate(8192);
        int readindex=-1;
        while((readindex=reader.read(charbuffer))!=-1){
          charbuffer.flip();
          temp+=charbuffer.toString();
          if(temp.indexOf(SOAP_BEGIN)!=-1 && temp.indexOf(SOAP_END)!=-1){
            //System.out.println(new Date().toLocaleString()+"server:"+temp);
            temp="";
            String str="receive the soap message hahahah";
            byte[] headbytes=str.getBytes();
            int length=headbytes.length;
            String l=String.valueOf(length);
            byte[] lengthbytes=l.getBytes();
            byte[] bytes=new byte[length+lengthbytes.length];
            int i=0;
            for(i=0;i<lengthbytes.length;i++){
              bytes[i]=lengthbytes[i];
            }
            for(int j=i,k=0;k<length;k++,j++){
              bytes[j]=headbytes[k];
            }
            System.out.println("server send:"+new String(bytes));
            writer.write(bytes);
            writer.flush();
          }else if(temp.indexOf(SOAP_BEGIN)!=-1){
            temp=temp.substring(temp.indexOf(SOAP_BEGIN));
          }
          if(temp.length()>1024*16){
            break;
          }
        }
      }catch(Exception e){
        e.printStackTrace();
      }finally{
        if(socket!=null){
          try{
            if(!socket.isClosed()){
              socket.close();
            }
          }catch(Exception e){
            e.printStackTrace();
          }
        }
      }
    }
  }
 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://blog.csdn.net/chaiqunxing51/article/details/51958242