0

I inherited code that calls the following:

TcpClient client;

// (removed try/catch blocks to simplify this discussion)
client = new TcpClient
{
  SendTimeout = 5000,
  ReceiveTimeout = 5000
};
client.Connect( hostName, port );

tcpClient.ReceiveTimeout = 20000;
tcpClient.SendTimeout = 20000;
tcpClient.Client.Send( someByteArray );

My question is why the Send/Receive timeouts would be set twice. Isn't it true that Connect isn't affected by those properties anyway? Am I missing something here? We got a SocketError.TimedOut exception on our Connect, but I don't think it has anything to do with hte timeout settings.

8
  • TCP is reliable and every Datagram (including Connect) gets an ACK Datagram. So a Datagram is an IP Header, TCP Header, and Data (if needed). See en.wikipedia.org/wiki/Transmission_Control_Protocol and learn.microsoft.com/en-us/dotnet/api/… Commented Jul 16 at 18:54
  • @jdweng wrong issue? Commented Jul 16 at 21:17
  • @CoryNelson : There is really two questions. 1) Timeout settings 2) Exception. I answered the first. The exception is due to the connection timing out. Connections timeout is either due to IP not found, it is taking too long for the connection to complete (the ACK is not getting returned). The connection timeout is a different setting than the ones posted. Commented Jul 16 at 21:27
  • Why would you even need to find out why some inherited code does some weird things? As I understand, the author of this code is not accessible, otherwise you would as this person. You need to understand the requirements to the code and meet them. What are you supposed to achieve? Why do you think you need those timeouts? Commented Jul 17 at 4:47
  • 1
    @JMVR that was my mistake in copying into this code. The values are actually 5000 and 20000. I will update that. Commented Jul 21 at 18:38

1 Answer 1

1

Isn't it true that Connect isn't affected by those properties anyway?

Correct, it's not affected by those, so the code in question is nonsense.

On Windows, the correct way to set a connection timeout is to use the TCP_MAXRT socket option. -1 means wait forever.

private const int TCP_MAXRT = 5;

public int GetConnectionTimeout(this TcpClient client)
{
    return (int)client.Client.GetSocketOption(SocketOptionLevel.TCP, (SocketOptionName)TCP_MAXRT);
}

public void SetConnectionTimeout(this TcpClient client, int timeoutSeconds)
{
    client.Client.SetSocketOption(SocketOptionLevel.TCP, (SocketOptionName)TCP_MAXRT, timeoutSeconds);
}

Having said that, in most cases it's easier to just use an async timeout on the C# side. It's also silly to be using TcpClient and then writing directly to the socket, you are supposed to use the NetworkStream.

For example:

using var client = new TcpClient();
tcpClient.ReceiveTimeout = 20;
tcpClient.SendTimeout = 20;
using (var cts = new CancellationTokenSource(5000)) // cancel after 5 seconds
{
    await client.ConnectAsync(hostName, port, cts.Token);
}

await tcpClient.GetStream().WriteAsync(someByteArray, someOtherCancellationTokenHere);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.