通过TCP接收字节数据包

时间:2016-09-02 19:53:00

标签: java tcp

我在JAVA中通过TCP接收字节数据包时遇到了一些问题。 我的TCPServer类发送207字节的数据包。当我发送一个数据包时,程序显示在控制台"读取207字节数据包。"并停止。使用下一个数据包,它继续执行,显示" Multiple Measurement"和 "读取1868767867字节包。"。之后接收永远停止。我不知道为什么它会收到1868767867个字节。我在wireshark和服务器上检查它总是发送207个字节。

这是我的TCPClient类:

public class TCPClient extends Thread {

private ServerSocket serverSocket; 
private Socket connectionSocket;
private InputStream inputStream;
private DataInputStream dataInputStream;


public TCPClient() throws IOException {
    try {
        serverSocket = new ServerSocket(Config.TCP_PORT);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Override
public void run() {

    try {
        connectionSocket = serverSocket.accept();
        inputStream = connectionSocket.getInputStream();
        dataInputStream = new DataInputStream(inputStream);
    } catch (IOException e) {
        e.printStackTrace();
    }
    while(true) {
        try {
            JsonObject json = getJsonFromTcp();
            if (json != null) {
                    String command = json.getAsJsonPrimitive("command").getAsString();
                    if(command.equals("multipleMeasurement")) {
                        executeMultipleMeasurement();
                    }
                }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

private JsonObject getJsonFromTcp() throws IOException {    

    byte[] buff = new byte[4];
    for(int i = 0; i < 4; i++) {
        buff[i] = dataInputStream.readByte();
    }

    int len = (((buff[3] & 0xff) << 24) | ((buff[2] & 0xff) << 16) | ((buff[1] & 0xff) << 8) | (buff[0] & 0xff));

    if(len > 0) {
        System.out.println("Read " + len + " byte packet.");
        byte[] data = new byte[len];
        dataInputStream.readFully(data);
        String jsonString = new String(data, "UTF-8");
        JsonParser jsonParser = new JsonParser();
        JsonObject json = jsonParser.parse(jsonString).getAsJsonObject();
        return json;
    }
    return null;
}

private void executeMultipleMeasurement() {
    System.out.println("Multiple Measurement");
}
}

任何人都知道解决方案吗?

1 个答案:

答案 0 :(得分:1)

查看数字1868767867,其字节为

"%c%c%c%c" % (0x7b,0x22,0x63,0x6f)
'{"co'

因此,您可以将下一条消息的前四个字节读作消息的长度。最可能的解释是,服务器每次发送正好207个字节的声明是服务器在总消息长度中包含长度前缀的长度(4个字节)。根据预期的协议,可能适合读取(长度为4)字节作为数据包的主体。

// Account for the length of the header
len -= 4;

if(len > 0) {
    System.out.println("Read " + len + " byte packet.");
    byte[] data = new byte[len];
    dataInputStream.readFully(data);

第二种可能性是服务器正在测量字符串中的字符数,然后使用该长度作为它将发送的utf-8转换字节缓冲区的长度,包括导致结果的一些非ascii字符缓冲时间更长。

如果没有看到服务器代码,就不可能确定这里发生了什么。