-1

I'm trying to implement a micro-benchmark for tcp socket communication though a loop of a send and receive messages. However, I've got a high latency compared to the standards latency of TCP socket in some diagrams. How can I improve my code ?

Server Side

    DataOutputStream output = new DataOutputStream(this.clientSocket.getOutputStream());
    DataInputStream input = new DataInputStream(this.clientSocket.getInputStream());
    int j = 0; 
    while (j < loop) {
        output.write(bytes);   
        input.read(new byte[input.readInt()] );             
        j++;
    }

Client Side

    DataOutputStream output = new DataOutputStream(socket.getOutputStream());
    DataInputStream input = new DataInputStream(socket.getInputStream());
    final long startTime = System.nanoTime();
    int j = 0;
    while (j < loop) {   
         input.read(new byte[input.readInt()]);
         output.write(bytes);
    j++;    
    }

    final long endTime = System.nanoTime();
    final double difference = (endTime - startTime) / 1e6;
    LOGGER.info("Latency:"+ difference/loop);
Ines
  • 3
  • 1
  • 4
  • Keep in mind that the accuracy of System.nanoTime() and System.currentTimeMillis() is system-dependent and may be not accurate enough for your use-case. – Felix Jun 07 '17 at 21:55
  • Standard latency? Latency will depend on network congestion which is something you can't control on the internet. Also, shouldn't you use the readFully method? read() can and will return fewer bytes than are requested. What is `bytes`? How do you define latency? – President James K. Polk Jun 07 '17 at 22:37

1 Answers1

1

Your code isn't even correct, so the results so far are meaningless. Quite possibly your senders are getting stuck because the application protocol isn't correctly implemented.

  • Nowhere do you actually write an int, yet both sides:

    1. read one int and
    2. assume it is a length word for the following message, which they then
    3. can fail to read completely because they are ignoring the result of read().

    A correct version of the same thing must start with somebody, apparently the server, writing the initial int.

  • You are also using unbuffered I/O, which is pretty expensive in the readInt() and writeInt() cases.

  • You are also creating tons of garbage at both ends unnecessarily.

Server:

DataOutputStream output = new DataOutputStream(ne w BufferedOutputStream(this.clientSocket.getOutputStream()));
DataInputStream input = new DataInputStream(new ByufferedInputStream(this.clientSocket.getInputStream()));
byte[] message - new byte[8192]; // or whatever
int msgLen = message.length;
while (j < loop)
{
    output.writeInt(msgLen);
    output.write(message);
    output.flush();
    int replyLen = input.readInt();
    input.readFully(message, 0, replyLen); // assuming replyLen <= msgLen
    j++;
}

Client (after constructing the data streams the same way and using the same message and msgLen variables:

while (j < loop) {
    mgLen = input.readInt();
    input.readFully(message, 0, msgLen); // same assumption as above
    output.writeInt(msgLen);
    output.write(message, 0, msgLen);
    output.flush();
    j++;    
}

E&OE

user207421
  • 305,947
  • 44
  • 307
  • 483