0
votes

I'm attempting to test packet loss across a TCP connection by comparing a messages sent counter maintained on the client side with a messages received counter on the server side. The messages I'm sending are 25 kilos with the first 5 bytes containing the count from the client in the form of a string padded with asterisks to maintain a 5 byte length. However after 3 or 4 successful messages the server fails to find the count. Is there something that I am forgetting to consider? My guess is that the server is having trouble keeping up with the client as the number of successful messages varies from 3 - 4 before error.

CLIENT SIDE CODE:

try{
        clientSocket = new Socket("192.168.0.15", SERVER_PORT);   
        DataInputStream in = new DataInputStream(clientSocket.getInputStream());
        DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
        int messageCounter = 0;
        byte [] message1 = new byte[25 * 1024];
        byte [] returnMessage1 = new byte[25 * 1024];
        byte [] count;
        long startTime1 = System.nanoTime();
        while (messageCounter < 100000) {
            System.out.println(messageCounter);
            addCountToMessage(formatCount(messageCounter).getBytes(), message1);
            out.write(message1);
            in.read(returnMessage1);     
            messageCounter ++;    
        }  
    }

SERVER SIDE CODE:

try {
      byte [] data = new byte[35 * 1024];
      System.out.println("STARTING LOOP");
      System.out.println("***********************************");
      int messageCounter = 0;
      int clientMessageCount = 0;
      String clientCountString = "";
      byte[] clientCount = new byte[5];

      while (true){
          in.read(data);
          clientCount[0] = data[0];
          clientCount[1] = data[1];
          clientCount[2] = data[2];
          clientCount[3] = data[3];
          clientCount[4] = data[4];

          clientCountString = new String(clientCount);
          System.out.println("Received Count String: \"" + clientCountString + "\"");
          clientCountString = clientCountString.replace("*", "");
          clientMessageCount = Integer.parseInt(clientCountString);

          System.out.println("Client Count: " + clientMessageCount + ", Server Count: " + messageCounter);
          out.write(data);
          System.out.println("***********************************");
          messageCounter ++;
      }
   }

OUTPUT OF SERVER:

java TCPServer

STARTING LOOP


Received Count String: "0****" Client Count: 0, Server Count: 0


Received Count String: "1****" Client Count: 1, Server Count: 1


Received Count String: "2****" Client Count: 2, Server Count: 2


Received Count String: "3****" Client Count: 3, Server Count: 3


Received Count String: ""

Exception in thread "Thread-0" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:481)
at java.lang.Integer.parseInt(Integer.java:527)
at Connection.run(TCPServer.java:52)
2

2 Answers

1
votes

I used to handle writing & reading of byte array as per below code, which always works for me even for mega bytes of data.

Example code for writing and reading byte array to and from socket

/* Write byte array */
OutputStream out = socket.getOutputStream(); 
DataOutputStream dos = new DataOutputStream(out);
int length = msgBytes.length;
dos.writeInt(length);
if (length > 0) {
    dos.write(msgBytes);
}

/*Read byte array */
DataInputStream dis = new DataInputStream(socket.getInputStream());
int length = dis.readInt();                   
if(length>0) {
    byte[] msgBytes = new byte[length];
    dis.readFully(msgBytes, 0, length); 
}
2
votes

There are a number of problems in the way you are doing this. The biggest is that you all calling read(byte[]) on your Socket, but never checking how many bytes have actually been read. You are also not reading the bytes that are supposedly being sent with the message after the header.

You might want to have a look at DataFetcher, my solution to dealing with (socket) input streams