在发送端的发送的是类似如下一个结构:
struct{
  int id;
  char title[50]
  int type;
};在java中如何读取类似的结构,并把它构造成一个类似以下的类:
class TestStruct{
  int id;
  String title;
  int type;
};

解决方案 »

  1.   

    我们是不是可以换一种形式来发送呢比如把这个结构转化成xml的形式 ,
      

  2.   

    要看你用的是什么socket类,如果是java.net.Socket的话,就直接从Socket的InputStream读取出数据,例如:byte[] buf = new byte[58];
    socket.getInputStream().read( buf );TestStruct test = new TestStruct();
    test.id = (buf[0]&0xFF) | ((buf[1]&0xFF) << 8) | ((buf[2]&0xFF) << 16) | ((buf[3]&0xFF) << 24);
    test.title = new String( buf, 4, 50 ); 
    test.type = (buf[54]&0xFF) | ((buf[55]&0xFF) << 8) | ((buf[56]&0xFF) << 16) | ((buf[57]&0xFF) << 24);
      

  3.   

    lutao050306() 
    什么啊.看了就头大啊.
    ---------------------------------------
    呵呵,小朋友当然看不懂了!
      
     
      

  4.   

    > 在java中,写socket通讯是如何读取从C++发过来的一个结构数据?我觉得,最好换一个视角看待这个问题。写 Java 程序,需要从 socket 里取出一个结构化的数据,不要想着这个数据是谁写进来的,只把它当作字节流看待就好了。这几个字节是什么,接下来的那几个字节是什么……然后把它组装到一个 object 里面去。同时,在 C++ 那头,也不要简单地 send((void*)&st, sizeof(st)),而是老老实实地把要传送的数据一个一个地发送出去。这样你就能保证发送的每一个字节都在你的控制之下,符合你自己制定的“传输协议”。
      

  5.   

    按你们这样是比较难实现的.
    可以用ASN.1 
    直接在不同语言中传送对象 结构数据等了
      

  6.   

    你给出的两个结构完全不能兼容。肯定不是用JNI解决问题就是了。
    我认同那个没有读过高中的人的建议。但是很好的适应性。其实让C++照顾一下Java的理解能力比较好,不要搞结构。
    然后用Axis就接受,就一马平川了。
      

  7.   

    > 你给出的两个结构完全不能兼容。也不能这么说吧。二进制(物理存储)级上的确*不兼容*,但从逻辑上讲,“一个整数/一个字符串/一个整数”,这又可以看作是*兼容*的。leehq(没有读过高中的人) 的方法思路是对的,但需要 C++ 那边的配合(可能这就是你说的“不要搞结构”),否则的话,通过 socket 传过来的未必是 58 个字节。顺便提一下,leehq(没有读过高中的人) 老兄的方法中,test.title = new String( buf, 4, 50 ); 有点问题,C++ 中的字符串是 null-terminated,并不一定是 50 个字节长。
      

  8.   

    maquan('ma:kju) :
    顺便提一下,leehq(没有读过高中的人) 老兄的方法中,test.title = new String( buf, 4, 50 ); 有点问题,C++ 中的字符串是 null-terminated,并不一定是 50 个字节长。
    -----------------------------------------------------------------
    你没看这个结构吗,怎么不是50个字长?
    struct{
      int id;
      char title[50]
      int type;
    };
      

  9.   

    大家没有遇到C结构体里面存在int[]德情况吧,想一想遇到这样的情况该如何处理呢?
      

  10.   

    > 你没看这个结构吗,怎么不是50个字长?
    > struct{
    >   int id;
    >   char title[50]
    >   int type;
    > };你误会我的意思了,我不是说这个结构里的字节数。这是一个有 50 字节的 char 数组,在 C/C++ 里能够表示一个不超过 49 字节的字符串。当你在 Java 中创建一个等价的字符串的时候,首先需要判断实际的字符串长度(按照 C/C++ 的语法,也就是 null-terminated),然后再去 new String(),而不应该直接 test.title = new String( buf, 4, 50 );
      

  11.   

    javaoaout(javaoaout) 
    大家没有遇到C结构体里面存在int[]德情况吧,想一想遇到这样的情况该如何处理呢?
    --------------------------------------------------------------------------------
    要看数组的长度,如果是int[4],那么长度就是4*sizeof(int)。maquan('ma:kju) 
    你误会我的意思了,我不是说这个结构里的字节数。这是一个有 50 字节的 char 数组,在 C/C++ 里能够表示一个不超过 49 字节的字符串。当你在 Java 中创建一个等价的字符串的时候,首先需要判断实际的字符串长度(按照 C/C++ 的语法,也就是 null-terminated),然后再去 new String(),而不应该直接 test.title = new String( buf, 4, 50 );
    ----------------------------------------------------------------------------------
    你说得不错,但我只是简单示范一下而已,具体的实现当然要变通一下了。
     
      

  12.   

    不用去理会对方是什么方式产生的该结构,java这边只需要将其理解成输入的数据流即可,在读取的时候按照对方约定的数据格式读取即可。就好比你读取一个位图文件,你不必去理会这个位图文件是用什么语言写的程序生成的一样,你只需要按照这个位图文件的格式读取就行了,这样的程序你可以用c++写,可以用C#写,也可以用java写。
      

  13.   

    建议使用SOAP通讯,这样简单多了
      

  14.   

    了解每种类型的字节数,高低位,就可以为所欲为了
    呵呵
    例子 double 
    long l; l = b[0];
    l &= 0xff;
    l |= ((long) b[1] << 8);
    l &= 0xffff;
    l |= ((long) b[2] << 16);
    l &= 0xffffff;
    l |= ((long) b[3] << 24);
    l &= 0xffffffffl;
    l |= ((long) b[4] << 32);
    l &= 0xffffffffffl; l |= ((long) b[5] << 40);
    l &= 0xffffffffffffl;
    l |= ((long) b[6] << 48); l |= ((long) b[7] << 56);
    return Double.longBitsToDouble(l);
      

  15.   

    发一段我的程序和linux下的C通讯的代码,希望对你有所启示.
    //发送获取资源列表的命令
                Log.log("\n 开始发送获取资源列表的命令:-----------------\n");
                outData.write(strHead.getBytes());
                outData.writeByte(version);
                outData.writeInt(reverseByte_32(serial));
                outData.writeShort(reverseByte_16(type));
                outData.writeShort(reverseByte_16(sub_type));
                outData.writeInt(reverseByte_32(len));
                outData.writeInt(reverseByte_32(result));
                outData.writeLong(reverseByte_32(timeout));            //接收返回信息
                Log.log("\n 开始接收~获取资源列表~返回信息:-----------------\n");
                byte head[] = new byte[16];
                inData.read(head);
                String strHead_b = new String(head, "GB2312");            byte version_b = inData.readByte();
                int serial_b = reverseByte_32(inData.readInt());
                short type_b = reverseByte_16(inData.readShort());
                short sub_type_b = reverseByte_16(inData.readShort());
                int len_b = reverseByte_32(inData.readInt());
                int result_b = reverseByte_32(inData.readInt());....
    .....=======================================================//java的16BIT的数据格式转换为C语言的数据格式。
        public static short reverseByte_16(int param) throws Exception {
            String order = SysConfig.loadSysConfig("System.byteOrder");
            if (order.equals("1")) { //高字节序传送数据,无须任何转换
                return (short) param;
            }
            int r1 = param & 0x000000ff;
            r1 <<= 8;
            param >>= 8;
            int r2 = 0x0000ffff & param;
            short result = (short) (r1 | r2);
            return result;
        }//java的32BIT的数据格式转换为C语言的数据格式。
        public static int reverseByte_32(int param) throws Exception {
            String order = SysConfig.loadSysConfig("System.byteOrder");
            if (order.equals("1")) { //高字节序传送数据,无须任何转换
                return param;
            }
            int r4 = param & 0x000000ff;
            r4 <<= 24;
            int r3 = param & 0x0000ff00;
            r3 <<= 8;
            param >>= 8;
            int r2 = param & 0x0000ff00;
            param >>= 16;
            int r1 = 0x000000ff & param;
            int result = (int) (r4 | r3 | r2 | r1);
            return result;
        }