现在有一个C++写的服务器,我要写一个java应用程序和他通信。
每次向服务器发送消息时,都是先发送一个数据包头,指明数据包体的长度和类型,再发送数据包体。class MsgHeader
{
    int DataType;
    int DataLength;
};也就是说,服务器接受消息时,每次都期望先接受到一个MsgHeader那么长的比特流,解析出DataType和DataLength,然后按照DataLength指明的长度,再接受对应的字节数作为消息体,最后根据DataType做相应的处理。我的问题是,在我的java应用程序中组织好数据包头并发送时,是不是应该用DataOutputStream来发送,应该如何发送呢?
如果不是话,又该怎么办呢?我是java初学者,麻烦大家了,谢谢!

解决方案 »

  1.   

    java可以直接用socket进行通信  比发包要方便
      

  2.   

    Socket socket = new Socket("URL", 80);//地址,端口号
    OutputStream ops = socket.getOutputStream();
    OutputStreamWriter opsw = new OutputStreamWriter(ops);
    BufferedWriter bw = new BufferedWriter(opsw);
    bw.write("你想发送的东东");
    bw.flush();
    bw.close();
      

  3.   

    Socket socket = new Socket("URL", 80);//地址,端口号
    OutputStream ops = socket.getOutputStream();
    OutputStreamWriter opsw = new OutputStreamWriter(ops);
    BufferedWriter bw = new BufferedWriter(opsw);
    bw.write("你想发送的东东");
    bw.flush();
    bw.close();
      

  4.   

    ObjectOutputStream 
    writeObject(Object obj) 
      

  5.   


            MsgHeader msgHeader = new MsgHeader();
            msgHeader.DataType = 12343;
            msgHeader.DataLength = 255;
            
            Socket socket = new Socket("URL", 80);// 地址,端口号
            DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
            try {
                //MsgHeader就依次写吧
                dos.writeInt(msgHeader.DataType);
                dos.writeInt(msgHeader.DataLength);
            } finally {
                dos.close();
            }
        
      

  6.   

    肯定是要用OutputStream的, 但是个人认为没有必要定义一个包头类, 应该自定义一个数据包封装类对OutputStream进行封装(同时可能需要解决java与c++在字节排序上不同的问题), 然后C++得到数据包后, 默认读取的第一个int为DataType, 第二个int为DataLength, 然后可能是消息正文, 例如:public class MyOutputBuffer { private ByteArrayOutputStream ios;
    private DataOutputStream iob; public MyOutputBuffer() {
    ios = new ByteArrayOutputStream();
    iob = new DataOutputStream(ios);
    } public int Size() {
    return ios.size();
    } public byte[] ToByteArray() {
    return ios.toByteArray();
    } public void Reset() {
    ios.reset();
    } public void Write(byte[] b) throws IOException {
    iob.write(b);
    } public void Write(byte[] b, int offset, int len) throws IOException {
    iob.write(b, offset, len);
    } public void WriteLong(long value) throws IOException {
    iob.writeLong(value);
    } public void WriteInt(int value) throws IOException {
    int tmp;
    tmp = (value << 24) | ((value << 8) & 0xFF0000) | ((value >> 8) & 0xFF00) | ((value >> 24) & 0xFF);
    iob.writeInt(tmp);
    } public void WriteUInt32(long value) throws IOException {
    int tmp;
    tmp = (int) (((value << 24) & 0xFF000000) | ((value << 8) & 0xFF0000) | ((value >> 8) & 0xFF00) | ((value >> 24) & 0xFF));
    iob.writeInt(tmp);
    } public void WriteShort(int value) throws IOException {
    int tmp;
    tmp = ((value << 8) & 0xFF00) | ((value >> 8) & 0xFF);
    iob.writeShort(tmp);
    } public void WriteChar(char value) throws IOException {
    int tmp;
    tmp = ((value << 8) & 0xFF00) | ((value >> 8) & 0xFF);
    iob.writeShort(tmp);
    } public void WriteStr(String value) throws IOException {
    int len, i;
    len = value.length();
    WriteInt(len);
    for (i = 0; i < len; i++) {
    WriteChar(value.charAt(i));
    }
    if ((len & 1) != 0) {
    WriteChar('\0');
    }
    } public void WriteUTF8(String value) throws IOException {
    if (value != null && value.length() > 0) {
    byte[] buf = value.getBytes("UTF-8");
    this.WriteInt(buf.length);
    iob.write(buf);
    } else {
    if (value != null)
    this.WriteInt(0);
    else
    this.WriteInt(-1);
    }
    } public void close() {
    try {
    ios.close();
    iob.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }可以这样使用:
    //构建消息体(例如)
    JMGSOutputBuffer ob = new JMGSOutputBuffer();
    ob.WriteInt(15);//消息类型
    ob.WriteInt(50);//消息长度
    byte[] bs = ob.ToByteArray(); //获取字节数组
    ob.close();//发送数据....
      

  7.   

    消息头也好,消息内容也好,在Socket里都是数据。
    所以你的问题是怎么发数据。至于怎么发数据,DataOutputStream只不过是封装了一下,提供了 writeInt, writeBoolean等一系列接口,本质上,还是 write(byte[]).这个实际上,就是一个序列化问题,就看你们之间的协议是怎么定的了。注意C++的程序有字节序的问题,所以不要迷信 DataOutoutStream 的 writeInt接口,可能对端的C++程序会解码错误。所以,协议!协议!还是协议! 你两个程序之间的协议要确定到每个字节序!所以才叫, 序列化 问题。
      

  8.   


    谢谢您的回复,我想问一下。
    我用ObjectOutputStream把一个MsgHeader对象写到一个byte数组中之后,发现数组的大小是62,这是为什么呢?
      

  9.   


    谢谢,刚才才知道,JVM是大端序的,而我写的C++服务器所用的CPU是小端序的,呵呵~