Java按照通讯协议,把读取到的byte序列一个一个地提取出来,并按照不同类型的大小组装成自己地对象。
难道你们原来用C就直接读写record啊?可移植性也太差了吧?要对两边的程序使用同类的CPU,并使用同样的编译参数编译。

解决方案 »

  1.   

    一言以蔽之,我用vc写了个服务器demo,现在要求java客户端发送一个雇员信息过来。
    雇员信息结构如下:
    struct UserInfo {
    char UserName[20];
    int UserId;
    };
    struct Employee {
    UserInfo user;
    float salary;
    };
    服务器端接受到后,对其进行填充再返回给java客户端,并显示出来。
    求大侠,版主等给我一个这样的java客户端代码,让我学习学习就明白了。服务器代码(vc6)
    #include "stdafx.h"
    #include "stdio.h"
    #include <WINSOCK2.H>struct UserInfo {
    char UserName[20];
    int UserId;
    };
    struct Employee {
    UserInfo user;
    float salary;
    };
    int main(int argc, char* argv[])
    {
    WSADATA wsaData;
    char buf[1024];
    int nBytes=1024,recvbytes;
    SOCKET Listening;
    SOCKET NewConnection;
    SOCKADDR_IN ServerAddr;
    SOCKADDR_IN ClientAddr;
    int ClientAddrLen=sizeof(ClientAddr);
    int Port=5050;WSAStartup(MAKEWORD(2,2),&wsaData);
    Listening=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    ServerAddr.sin_family=AF_INET;
    ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY);
    ServerAddr.sin_port=htons(Port);bind(Listening,(SOCKADDR *)&ServerAddr,sizeof(ServerAddr));
    listen(Listening,5);
    printf("Wating accpet....\n");
    NewConnection=accept(Listening,(SOCKADDR *)&ClientAddr,&ClientAddrLen);
    printf("Wating recv.....\n");if((recvbytes=recv(NewConnection,buf,nBytes,0)) == SOCKET_ERROR)
    {
    printf("\nErrorcode=%d, Recv from client\n",WSAGetLastError());
    return 0;
    }
    Employee *data = new Employee;
    data = (Employee *)&buf;printf("Userid: %d Username: %s",data->user.UserId,data->user.UserName);
    data->user.UserId = 007;
    strcpy(data->user.UserName,"Test");
    data->salary = 800;send(NewConnection,buf,recvbytes,0);return 0;
    }
      

  2.   

    在google 搜java c++ socket有下面信息,偏偏我有开不开.
    Java / C++ socket class - [ 翻译此页 BETA ]
    ... If you need to do socket communication between a Java and/or C++ programs,
    you've come to the right place. ... a fairly basic class that can be used to
    communicate between Java applications and C++ programs via a socket connection. ...
    www.keithv.com/project/socket.html - 7k - 网页快照 - 类似网页
      

  3.   

    版主 高手们来看看。没的办法,应为服务器端不能改。客户端改java是想用它的web start. 
    我刚学java,java不像c++中有结构体, 
    由于定义了大量的通讯帧,我用class来包装通讯帧,在传输双方 又不一致,该怎么办?
      

  4.   

    希望对你有所帮助:
    http://blog.csdn.net/kingfish/archive/2005/03/29/333635.aspx
      

  5.   

    谢谢!这对我很有帮助。
    仔细一想,实际上是我对vc,java怎么序列化数据不了解(由于vc,java的各种基本数据类型存放为byte格式有所区别)
    当然首先要明确,发送C++中socket消息帧,实际上是消息帧的各个基本数据类型 加在一起发送出去,所以帧的长度的就是各个基本数据类型的长度之和。而java中没有数据结构,也不可能把class发送出去(因为它串行化后的内容远远不止class包含的类变量),所以我在消息帧的class中加入byte[],和c++ socket通讯就靠byte[]。经过思考,我把通讯中所有的消息帧都包装成如下,class的类变量即消息帧中的各个字段和byte[]。
    下面这个例子还有很多只得修改的,int,long,float与byte[]的转换(昨天搞了一下午,而且这种写法肯定有些问题)不知道我的这种做法合不合适,请大家看看帮我改改,谢了。
    最后说说,原本服务器是vc 客户端delphi,后来想把客户端写为rich client,所以就移植为java.import java.net.Socket;
    import java.nio.ByteBuffer;
    import java.nio.BufferUnderflowException;public class Employeeframe {
      public String UserName;
      public int UserId;
      public float salary;
      public byte[] employeebyte = new byte[28];
      public Employeeframe() {
      }  // 接受到的 消息帧 的byte流,转化为字段
      public Employeeframe(byte[] bytes) {
        if (bytes.length == 28) {
          byte[] tmp = new byte[20];
          System.arraycopy(bytes, 0, tmp, 0, 20);
          UserName = new String(tmp);
          System.arraycopy(bytes, 20, tmp, 0, 4);
          UserId = bytes2int(tmp);
          System.arraycopy(bytes, 24, tmp, 0, 4);
          salary = bytes2float(tmp);
        }
      }
    //得到消息帧 的byte流,发送这个东西给c++ socket server
      public Employeeframe(String name,int id,float salary){
        this.UserName = name;
        this.UserId = id;
        this.salary = salary;
        byte[] temp = name.getBytes();
        System.arraycopy(temp,0,employeebyte,0,temp.length);
        temp = int2bytes(id);
          System.arraycopy(temp, 0, employeebyte, 20, temp.length);
          temp = float2bytes(salary);
          System.arraycopy(temp, 0, employeebyte, 24, temp.length);
      }
      //以下是针对C++ 和 Java 各种基本数据结构 与Byte[]的变换,
      //注意在C++中int float long都是低字节在前,而java正好相反 
     public static float bytes2float(byte[] b){
       ByteBuffer bb = ByteBuffer.allocate(4);
       for(int i = 3;i>-1;i--)
         bb.put(b[i]);
       try{
         float f = bb.getFloat();
         return f;
       }catch(BufferUnderflowException e){
         e.printStackTrace();
         return 0.0f;
       } 
     } public static byte[] float2bytes(float f) {
     return int2bytes(Float.floatToRawIntBits(f));
     } 
     public static int bytes2int(byte[] b)
     {
     int s = 0;
     for(int i=3;i>-1;i--){
       s *= 256;
       s += b[i]<0?b[i]+256:b[i];
     }
     return s;
     }
     public static byte[] int2bytes(int n)
     {
     byte[] b = new byte[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;
     }
     public static String bytes2string(byte[] b,int length){
       return new String(b,0,length); 
     }
     public static byte[] string2bytes(String s,int length){
       while(s.getBytes().length<length)
        s+="\0";
      return s.getBytes();
     }
    public static void main(String args[]){
      try {
       Socket sock = new Socket("127.0.0.1", 5050);
       sock.getOutputStream().write(emp1.employeebyte);
       sock.getInputStream().read(temp);
       Employeeframe  emp2 = new Employeeframe(temp);
       System.out.println(emp2.UserName);
       System.out.println(emp2.UserId);
       System.out.println(emp2.salary);
       sock.close();
     }
     catch (Exception e) {
       e.printStackTrace();
     }
    }
    }