YoloQ
YoloQ

Reputation: 45

Slow tcp connection causes my app to stall

I have found a class that handles TCP connections and I am using it to communicate with a gaming service. All was working fine until I realized that my application was stalling if the connection speed was slower. I have a thread polling let's say every 30 seconds.

I got the TCPClient class I use from this thread Java TCP sending first message, then infinite wait

This service requires 2 steps to verify a request. You first send a hash and you receive and acknowledge. Then you send the the actual request and you receive the response.

public byte[] getResponse(byte[] hash, byte[] request) throws Exception{
    if(client == null || client.socket.isClosed() || !client.socket.isConnected() 
    || client.socket.isInputShutdown() || client.socket.isOutputShutdown(){
        client = new TCPClient(this.host, this.port);
    }
    client.SendToServer(hash);
    byte[] ack = client.ReceiveFromServer();

    if(checkAck(ack, getAckForRequest(request))){
        client.SendToServer(request);
        byte[] response = client.ReceiveFromServer();

        return response;
    }
}

My code looks something like this. I simplified it a bit to make it more readable.

I am using this function inside a try/catch block and when it throws an exception I store the request in a MySQL database.

Is there a way to avoid blocking my main thread if the connection is slow and do the same stuff?

Upvotes: 1

Views: 340

Answers (1)

WillShackleford
WillShackleford

Reputation: 7018

Is there a way to avoid blocking my main thread if the connection is slow and do the same stuff?

Yes. One can call setSoTimeout() on a Socket.

The Oracle documentation:

https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#setSoTimeout-int-

Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.

If you just want to close the connection and give up it works well. If you want to resume the action later you have to keep track of the bytes already read which means just having more threads is usually an easier option.

Upvotes: 1

Related Questions