java socket報文通訊(二)報文的封裝

來源:互聯網
上載者:User

標籤:

昨天我們談了怎麼建立socket通訊的服務端和用戶端,今天我們就來談一談怎麼封裝報文。

什麼是報文這裡我就不在闡述了,不清楚的朋友可以自己去查資料。我們今天要談的報文主要友以下幾個部分組成:

3位同步校正位+8位報文長度+報文頭+報文體+32位MD5校正位

基本格式如下:

0X110X120X1300000232<?xml version="1.0" encoding="GBK"?><ROOT><Code>0204</Code><Date>20141223</Date><No>141223010008152</No><Code>17010001</Code><Name>張三</Name></ROOT>B251AB76B11114DB176023A0AA27A524

說明:

  前面的0X110X120X13是3位16進位的同部位,這裡為了大家理解,所以就以字元的形式謝出來了。00000232是報文長度。<?xml version="1.0" encoding="GBK"?><ROOT><Code>0204</Code><Date>20141223</Date><No>141223010008152</No><Code>17010001</Code></ROOT>是報文頭。即每個報文都包含的資訊。<Name>張三</Name>是報文體。B251AB76B11114DB176023A0AA27A524是加密資料。

關於如何將對象轉換為xml格式的報文我將在下一篇寫,這裡主要是給大家如何將如上的這些字串轉化為位元組以及如何發送和接收報文。

1.建立報文的對象

public class SocketPacket {    private String bodyLen;    private String body;    private String syncStr;    private String md5;    public String getBodyLen() {        return bodyLen;    }    public String getBody() {        return body;    }    public String getSyncStr() {        return syncStr;    }    public String getMd5() {        return md5;    }    public void setBodyLen(String bodyLen) {        this.bodyLen = bodyLen;    }    public void setBody(String body) {        this.body = body;    }    public void setSyncStr(String syncStr) {        this.syncStr = syncStr;    }    public void setMd5(String md5) {        this.md5 = md5;    }            public byte[] getByteStream() throws UnsupportedEncodingException{        byte[] bodyBytes = this.body.getBytes("gbk");//獲得body的位元組數組        int bodyLength = bodyBytes.length;        int socketLength = 3+bodyLength+8+32;        byte [] soc = new byte[socketLength];        //添加校正資料        int index = 0;        soc[0]=0x11;        soc[1]=0x12;        soc[2]=0x13;        index+=3;        //添加8位報文長度(我的博文中也有NumberFormat的用法介紹)        NumberFormat numberFormat = NumberFormat.getNumberInstance();        numberFormat.setMinimumIntegerDigits(8);        numberFormat.setGroupingUsed(false);        byte [] num = numberFormat.format(socketLength).getBytes();        for(int i = 0;i<8;i++){            soc[index++]= num[i];        }        //添加body內容        for(int i = 0;i<bodyLength;i++){            soc[index++] = bodyBytes[i];        }        //添加md5校正碼        byte [] md5Bytes = this.md5.getBytes();        for (int i = 0; i < num.length; i++) {            soc[index++] = md5Bytes[i];        }        return soc;    }        //位元組裝轉報文string    public String getString(byte [] socketBytes){        String syncStr = this.bytesToString(socketBytes, 0, 3);        String socketLength = this.bytesToString(socketBytes, 3, 3+8);        String body = this.bytesToString(socketBytes, 3+8, socketBytes.length-32);        String md5 = this.bytesToString(socketBytes,socketBytes.length-32,socketBytes.length);        return syncStr+socketLength+body+md5;    }        //將位元組數組轉化為string    public String bytesToString(byte [] bytes,int start,int end){        String str = "";        if(bytes.length<end-start){            return str;        }        byte [] bs = new byte[end-start];        for(int i = 0;i<end-start;i++){            bs[i] = bytes[start++];        }        str = new String(bs);        return str;    }        public String toString(){        return this.syncStr+this.bodyLen+this.body+this.md5;    }    }

2.封裝發送和接收報文的工具類

/** * 報文發送 */public class SockeUtil {    Socket socket = null;    public SockeUtil(String ip,int port) throws UnknownHostException, IOException{        socket = new Socket(ip, port);    }    //    public SocketPacket sentSocket(SocketPacket socketPacket) throws UnsupportedEncodingException, IOException{        SocketPacket sPacket = new SocketPacket();        OutputStream output=null;        InputStream input =null;        // 同步字串(3byte)        byte[] sync = null; //        byte[] bodyLen = null; // 8位長度        byte[] body = null; // 內容        byte[] md5 = null;  // MD5        output = socket.getOutputStream();        //寫資料發送報文        output.write(socketPacket.getByteStream());        //獲得服務端返回的資料        input = socket.getInputStream();        sync = this.streamToBytes(input,3);        bodyLen = this.streamToBytes(input, 8);        String lenString = new String(bodyLen);        int len = Integer.valueOf(lenString);        body = this.streamToBytes(input, len);        md5 = this.streamToBytes(input, 32);        sPacket.setSyncStr(new String(sync,Charset.forName("gbk")));        socketPacket.setBodyLen(new String(bodyLen,Charset.forName("gbk")));        socketPacket.setBody(new String(body,Charset.forName("gbk")));        socketPacket.setMd5(new String(md5,Charset.forName("gbk")));        return sPacket;    }        public byte[] streamToBytes(InputStream inputStream,int len){        /**         * inputStream.read(要複製到得位元組數組,起始位置下標,要複製的長度)         * 該方法讀取後input的下標會自動的後移,下次讀取的時候還是從上次讀取後移動到的下標開始讀取         * 所以每次讀取後就不需要在制定起始的下標了         */        byte [] bytes= new byte[len];        try {            inputStream.read(bytes, 0, len);        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return bytes;    }}

3.在封裝一個調用報文發送的類:

public String socket(SocketPackage socketPackage) throws UnsupportedEncodingException{                SocketClient socketClient=null;;        try {            socketClient = new SocketClient(ip,連接埠);        } catch (UnknownHostException e) {            log.error("socket連結異常,連結資訊:"+ip+連接埠);            e.printStackTrace();        } catch (IOException e) {            log.error("socket IO異常");            e.printStackTrace();        }               SocketPackage s = null;        try {            s = socketClient.sendMsg(socketPackage);        } catch (Exception e) {            try {                log.error("socket發送訊息異常,發送資訊:"+new String(socketPackage.getByteStream(),"GBK"));            } catch (UnsupportedEncodingException e1) {                log.error("socket將socketPackage轉為字串異常,socketPackage資訊:"+socketPackage.getByteStream());                e1.printStackTrace();            }            e.printStackTrace();        }               String result = "";        try {             result = new  String(s.getStream(),"GBK");        } catch (UnsupportedEncodingException e) {            log.error("socket將socketPackage轉為字串異常,socketPackage資訊:"+socketPackage.getByteStream());            e.printStackTrace();        }        return result ;  }

 這樣我們就能發送報文和接收報文了!趕緊試一下吧!^_^

java socket報文通訊(二)報文的封裝

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.