Java调用DataOuputStream的write方法写入数据第一个字节不知所踪
澳门赌场开户
澳门赌场开户
当前位置 : 澳门赌场开户 > 网上赌博新址

Java调用DataOuputStream的write方法写入数据第一个字节不知所踪

该问题源于最近做的项目,对方系统每次接收TCP字节流先读取前四个字节来确定后续消息体的长度,
因此我这边需要调用某个方法将消息体的长度写入流的前四个字节。
根据java文档对DataOuputStream对writeInt的描述

Writes an int to the underlying output stream as four bytes, high byte first. If no exception is thrown, the counter written is incremented by 4.

writeInt这个方法刚好能满足这个需求,于是调用该方法,代码如下:

dos.writeInt66666666;

注:dos为DataOuputStream的实例。

但是通过抓包发现只写入了三个字节,如下图所示:

66666666的4字节16进制表示为0x03F940AA
而上图缺少了03这一字节

以下代码也是一样的结果:

  len = 66666666;
  dos.writelen >>> 24 & 0xFF;
  dos.writelen >>> 16 & 0xFF;
  dos.writelen >>>  8 & 0xFF;
  dos.writelen >>>  0 & 0xFF;

以下代码打印数字66666666的4字节16进制表示:

public static void printHexStringbyte[] b
{
    for int i = 0; i < b.length; i++
    {
        String hex = Integer.toHexStringb[i] & 0xFF;
        if hex.length == 1
        {
            hex = 0 + hex;
        }
        System.out.printhex.toUpperCase + " ";
    }
    System.out.println"";
}
int len = 66666666;
byte[] temp = {
    bytelen >>> 24 & 0xFF,
    bytelen >>> 16 & 0xFF,
    bytelen >>>  8 & 0xFF,
    bytelen >>>  0 & 0xFF    
};
printHexStringtemp;

输出结果为:03 F9 40 AA

之后又用以下代码试探了一下:

  dos.write0x20;
  dos.write0x00;
  dos.write0x00;
  dos.write0x02;
  dos.write0x93;
      

抓包:

少了20这个字节。
这几天一直被这个问题困扰,希望有人能指点迷津,谢谢!

你处理TCP粘包问题了吗?
既然是TCP就不得不考虑粘包的问题。粘包问题不解决的话,你没办法确定哪些字节才是一个包的开头4个字节。

简言之就是,你收到一大堆字节,然后这些字节的来源可能如下:

  • 两三个包的所有字节一起发过来

  • 前一个包的后半部分和后一个包的前半部分字节一起发过来

  • 总之,就是半包或者粘包的混合

我们用的是netty,tcp粘包的问题,这里有一个很好阐述和基于netty的解决方案:https://my.oschina.net/andylu...

不抓包在直接在java里面input流读出来是什么?

这属于socket通信包头问题,我之前的项目是这么处理的,代码段如下:

sendString url, int port, String content{
    Socket socket = null;
    OutputStream out = null;
    DataOutputStream dataOutputStream = null;
    try {
        socket = new Socketurl, port;
        out = socket.getOutputStream;
        dataOutputStream = new DataOutputStreamout;
        dataOutputStream.writeIntcontent.getBytes.length;
        dataOutputStream.writecontent.getBytes;
        dataOutputStream.flush;
        ...
    }
}

建议写一个接收socket来Debug调试,抓包工具没用过.或者和对方联调,对方能收到并成功解析就OK了,不需要在抓包上钻牛角尖.
希望能帮到你~

调用flush了没?

栏目列表

广告位

澳门赌场开户