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

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

客户端:

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();
    }

  }
}

服务端:

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();
          }
        }
      }
    }
  }

}

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

02-02 09:45