java 和C++ Socket程序发送结构体

       主要技术问题:windows,linux等系统采用LITTLE_ENDIAN字节序,而java自身采用BIG_ENGIAN字节序,BIG_ENGIAN是指低地址存放最高有效字节(MSB),而LITTLE_ENDIAN则是低地址存放最低有效字节。Java程序写的客户程序端同c++的服务端程序交互时结构体的某些数据类型需要转换字节序。本文解决方法,java客户端程序发送数据时做相应的转换字节序,等收到数据时再做一次字节序的转换。

       现在的网络程序多数采用可靠交付的TCP协议,其采用字节流的传输方式,c++程序中用结构体来模拟报头以此界定每次发送的报文。所以网络中整个字节流的格式:报头+数据负载+报头+数据负载……

      本文基于c++写服务端和java写客户端应用场景描述。服务端程序收到客户端发送的报文后将原报文做一个回射。

采用报头:

Struct Header{

         Intcmd;            //标示报文用途

         Intlength;        //数据负载长度

         Intpara1;                   //服务端处理完结果

Int para2;                   //服务端处理完结果

Int para3;                   //服务端处理完结果

}; 此时套接口的读写方式为先读报头,在报头中取出数据负载的长度,然后再读相应字节的数据。

        

Java客户端代码:

报头类:

publicclassMsgHeader {

    privateintcmd;

    privateintlength;

    privateintpara1;

    privateintpara2;

    publicint getCmd() {

        returncmd;

    }

    publicvoid setCmd(int cmd) {

        this.cmd = cmd;

    }

    publicint getLength() {

        returnlength;

    }

    publicvoid setLength(int length) {

        this.length = length;

    }

    publicint getPara1() {

        returnpara1;

    }

    publicvoid setPara1(int para1) {

        this.para1 = para1;

    }

    publicint getPara2() {

        returnpara2;

    }

    publicvoid setPara2(int para2) {

        this.para2 = para2;

    }

    publicint getPara3() {

        returnpara3;

    }

    publicvoid setPara3(int para3) {

        this.para3 = para3;

    }

    privateintpara3;

   

    public MsgHeader()

    {

        this.cmd = 0;

        this.length = 0;

        this.para1 = 0;

        this.para2 = 0;

        this.para3 = 0;

    }

    public MsgHeader(int cmd,int length,int para1,int para2,int para3){

        this.cmd=cmd;

        this.length= length;

        this.para1 = para1;

        this.para2 = para2;

        this.para3 = para3;

    }

}

公共操作类:

publicclassCommon {

    //字节序转换

    publicstaticbyte[] toLH(int n) {

        byte[] b =newbyte[4];

        b[0]= (byte)(n & 0xff);

        b[1]= (byte)(n >> 8 & 0xff);

        b[2]= (byte)(n >> 16 & 0xff);

        b[3]= (byte)(n >> 24 & 0xff);

        return b;

    }

    //btye数组转换为int

    publicstaticint bytes2Integer(byte[] byteVal) {

        int result = 0;

        for (int i = 0; i < byteVal.length; i++) {

            int tmpVal = (byteVal[i]<< (8 * (3 - i)));

            switch (i) {

            case 0:

                tmpVal= tmpVal & 0xFF000000;

                break;

            case 1:

                tmpVal= tmpVal & 0x00FF0000;

                break;

            case 2:

                tmpVal= tmpVal & 0x0000FF00;

                break;

            case 3:

                tmpVal= tmpVal & 0x000000FF;

                break;

            }

            result= result | tmpVal;

        }

        return result;

    }

}

协议类:

publicclassProtocol {

    publicstaticfinalintPORTAL_DBC_INSTALLSYSTEM= 0x05000030;

    publicstaticfinalintPORTAL_DBC_INSTALLSYSTEM_ACK= 0x05000031;

   

    /*

     * add all protocol

     *

     *

     *

     */

   

   

}

数据收发类:

publicclassDBCAgent {

    private Socketsocket = null;

    privatebyte[]buffer;

    public DBCAgent() {

        try {

            this.socket =new Socket("192.168.9.64",8886);

 

        }catch(UnknownHostException e) {

            //TODO Auto-generated catch block

            e.printStackTrace();

        }catch(IOException e) {

            //TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

    //收数据

    publicvoid recvData()throws IOException {

        byte[] recvHead =newbyte[4];

        int cForm;

        intcmd, length, para1,para2, para3;

 

        // readcmd转换字节序

        socket.getInputStream().read(recvHead,0, 4);

        cForm= Common.bytes2Integer(recvHead);

        cmd= Common.bytes2Integer(Common.toLH(cForm));

 

        // read length转换字节序

        socket.getInputStream().read(recvHead,0, 4);

        cForm= Common.bytes2Integer(recvHead);

        length= Common.bytes2Integer(Common.toLH(cForm));

 

        // read para1转换字节序

        socket.getInputStream().read(recvHead,0, 4);

        cForm= Common.bytes2Integer(recvHead);

        para1= Common.bytes2Integer(Common.toLH(cForm));

 

        // read para2转换字节序

        socket.getInputStream().read(recvHead,0, 4);

        cForm= Common.bytes2Integer(recvHead);

        para2= Common.bytes2Integer(Common.toLH(cForm));

 

        // read para3转换字节序

        socket.getInputStream().read(recvHead,0, 4);

        cForm= Common.bytes2Integer(recvHead);

        para3= Common.bytes2Integer(Common.toLH(cForm));

 

        byte[] recvData =newbyte[length];

 

        // read data

        socket.getInputStream().read(recvData,0, length);

        StringDataStr = newString(recvData);

 

        System.out.println(DataStr);

    }

发数据类:

    publicboolean sendData(String data) {

        byte[] temp =null;

        MsgHeaderheader = newMsgHeader();

        header.setLength(data.length());

 

        this.buffer =newbyte[data.length() + 20];

 

        // addcmd 转换字节序

        temp= Common.toLH(Protocol.PORTAL_DBC_INSTALLSYSTEM);

        System.arraycopy(temp,0,buffer,0, 4);

 

        // addlength转换字节序

        temp= Common.toLH(header.getLength());

        System.arraycopy(temp,0,buffer,4, 4);

 

        // add para1转换字节序

        temp= Common.toLH(header.getPara1());

        System.arraycopy(temp,0,buffer,8, 4);

 

        // add para2转换字节序

        temp= Common.toLH(header.getPara2());

        System.arraycopy(temp,0,buffer,12, 4);

 

        // add para3转换字节序

        temp= Common.toLH(header.getPara3());

        System.arraycopy(temp,0,buffer,16, 4);

 

        System.arraycopy(data.getBytes(),0,buffer,20, data.length());

 

        try {

            socket.getOutputStream().write(this.buffer);

        }catch(IOException e) {

            //TODO Auto-generated catch block

            e.printStackTrace();

        }

 

        returntrue;

    }

}

 

测试类:

publicclassTest {

    /**

     * @param args

     * @throws IOException

     */

    publicstaticvoid main(String[] args)throws IOException {

        //TODO Auto-generated method stub

       

        DBCAgentdbcAgent = newDBCAgent();

       

//发送数据

        dbcAgent.sendData("Helloaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

        //接收数据

dbcAgent.recvData();

        try {

            Thread.sleep(10000);

        }catch(InterruptedException e) {

            //TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

}

猜你喜欢

转载自blog.csdn.net/zouhaozl2008/article/details/8083835