crulalbani crulalbani - 3 months ago 17
Java Question

Receiving byte packets by TCP

i have some problem with receive byte packets by TCP in JAVA.
My TCPServer class sending 207 - byte packets. When I send one packet, program display in console "Read 207 byte packet." and stops. With next packet it continue execution, display "Multiple Measurement" and
"Read 1868767867 byte packet.". After that receiving is stopped forever. I don't know why 1868767867 bytes it receive. I check it in wireshark and server sending always 207 bytes.

This is my TCPClient class:

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");
}
}


Anyone know solution?

Answer

Looking at the number 1868767867, its bytes are

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

So you could be reading the first four bytes of the next message as the length of the message. The most likely explanation given the claim that the server sends exactly 207 bytes each time is that the server includes the length of the length prefix (4 bytes) in the total message length. Depending on the intended protocol, it might be appropriate to read (length - 4) bytes as the body of the packet.

// 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);

A second possibility is that the server is measuring the number of characters in a string and then using that length as the length of the utf-8 converted byte buffer that it will send, including some non-ascii characters that cause the resulting buffer to be longer.

Without seeing the server code, it's impossible to be certain which is happening here.

Comments