I have a TCP server which has a receive timeout of 9 seconds, however, I am using to receive any data from the client:
while (sr.Peek() >= 0) {
line += sr.ReadLine();
line += Environment.NewLine;
}
But when the server times out I get the following error on the sr.Peek() line:
System.IO.IOException: Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
Is there a way of having a timeout but also waiting for any potential data from the client?
Related
I am getting the following exception in cluster.Connect while performing load testing in my application.
All hosts tried for query failed (tried :: SocketException 'A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond'; :: SocketException 'A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond'; ...)
The exception is thrown only when I overwhelm my application with a large number of requests (1000 or more). However, it seems to work fine for small number of requests because of which I am eliminating the possibility of a firewall issue. For some reason, this call gets stuck which leads to a deadlock in my application. Any help is greatly appreciated. Thanking in advance.
Regards,
Sitakanta Mishra
I'd like to wait for a slow response from a client with TcpClient but get a timeout after about 20s no matter how I configure it. This is my attempt:
using (var client = new TcpClient { ReceiveTimeout = 9999999, SendTimeout = 9999999 })
{
await client.ConnectAsync(ip, port);
using (var stream = client.GetStream())
{
// Some quick read/writes happen here via the stream with stream.Write() and stream.Read(), successfully.
// Now the remote host is calculating something long and will reply if finished. This throws the below exception however instead of waiting for >20s.
var bytesRead = await stream.ReadAsync(new byte[8], 0, 8);
}
}
The exception is an IOException:
Unable to read data from the transport connection: A connection
attempt failed because the connected party did not properly respond
after a period of time, or established connection failed because
connected host has failed to respond.
...which contains a SocketException inside:
A connection attempt failed because the connected party did not
properly respond after a period of time, or established connection
failed because connected host has failed to respond
SocketErrorCode is TimedOut.
The 20s seems to be an OS default on Windows but isn't it possible to override it from managed code by interacting with TcpClient? Or how can I wait for the response otherwise?
I've also tried the old-style BeginRead-EndRead way and the same happens on EndRead. The problem is also not caused by Windows Firewall or Defender.
I'd like to wait for a slow response from a client
It's important to note that it's the connection that is failing. The connection timeout is only for establishing a connection, which should always be very fast. In fact, the OS will accept connections on behalf of an application, so you're literally just talking about a packet round-trip. 21 seconds should be plenty.
Once the connection is established, then you can just remove the ReceiveTimeout/SendTimeout and use asynchronous reads to wait forever.
It turns out that the remote host wasn't responding in a timely manner, hence the problem. Let me elaborate, and though this will be a solution very specific to my case maybe it will be useful for others too.
The real issue wasn't a timeout per se, as the exception indicated, but rather what exceptions thrown on subsequent Read() calls have shown: "An existing connection was forcibly closed by the remote host"
The remote host wasn't purposely closing the connection. Rather what happened is that when it was slow to respond it was actually so busy that it wasn't processing any TCP traffic either. While the local host wasn't explicitly sending anything while waiting for a response this still was an issue: the local host tried to send ACKs for previous transmissions of the remote host. Since these couldn't be delivered the local host determined that the remote host "forcibly closed" the connection.
I got the clue from looking at the traffic with Wireshark (always good to try to look at what's beneath the surface instead of guessing around): it was apparent that while the remote host was busy it showed complete radio silence. At the same time Wireshark showed retransmission attempts carried out by the local host, indicating that this is behind the issue.
Thus the solution couldn't be implemented on the local host either, the behavior of the remote host needed to be changed.
I would like to know on TcpClient's NetworkStream what exactly happen if timeout occurs.
While debugging the code i found that after request is sent and if no data is received within mention timeout period it throws below exception and unfortunately closes the connection (TcpClient.Connected become false):
Unable to read data from the transport connection: A connection
attempt failed because the connected party did not properly respond
after a period of time, or established connection failed because
connected host has failed to respond.
It throws the exception is okay, but i would like to know how i can prevent it from closing the connection.
It would be great if someone can provide more insights on this.
Have you checked this one? Reconnect TCPClient after interruption I think if you have a long enough TTL of your TCP Connection, should an exception occurs (I believe you would get thrown a SocketException) you can catch that up and initiate your retry logic. There are several implementations for this and obviously that would depend on the use case but normally there is a number of attempts (configuration value) before "giving up" connecting. That way your manager will retry connecting X number of times and will carry on if there is a successful connection otherwise will propagate up in the chain the exception.
I've experienced some random TCP disconnection in production environment: A high load server in Windows Embedded and a client in Windows XP sit in a LAN, connected by long lived TCP via a Switcher, most data flow is from server to client.
The server side core code is straight forward and I simplified as:
try
{
TcpListener tcpListener = new TcpListener(System.Net.IPAddress.Any, 8190);
tcpListener.Start();
var tcpClient = tcpListener.AcceptTcpClient();
var ns = tcpClient.GetStream();
ns.Write(bytes);
}
catch (Exception ex)
{
}
the random exception in that catch is:
System.IO.IOException: Unable to write data to the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
I understand this exception as client has no response (some underlying TCP level ACK or sth) to certain TCP request from server, but the problem is in some cases, the exception just raised up in 4 or 5 seconds from that ms.WriteTo(ns); called.
So the question 1, since I didn't specify any timeout values for TcpClient object, why the Write timeout so short? possible the TCP have the dynamic timeout settings when connection established(based on Round Trip Time or sth), but should be longer(I guess).
==============================
I then write a small program to simulate the situation, I periodically send data from server to client, suddenly I unplug the cable in client machine, what surprise me is the ns.Write(bytes) in server side still can be called smoothly like an async call does, but not the expected blocking call and exception would pop up right after I unplugged the cable.
SO the question 2, if the Write behaves like this, then we never know what data has been successfully send to other side, and this is why we use TCP.
===============================
with cable unplugged, I still keep Write data, I noticed when the data I send reached certain amount (probably 100 bytes), and then the offline time reached 30 seconds, exception raised and also confused me:
System.IO.IOException:
Unable to write data to the transport connection: An existing
connection was forcibly closed by the remote host. --->
System.Net.Sockets.SocketException: An existing connection was
forcibly closed by the remote host at
System.Net.Sockets.Socket.Send(Byte[] buffer, Int32 offset, Int32
size, So cketFlags socketFlags) at
System.Net.Sockets.NetworkStream.Write(Byte[] buffer, Int32 offset,
Int32 size)
If I just send few bytes, there's no exception at all forever.
SO the question 3, TCP data failed to reach other side might not raise any notification in sender side?
And the question 4, who closed the connection in the exception described? I expected a time out exception here since client side totally disappear.
I am trying to connect to gateway.sandbox.push.apple.com through "apns-sharp" class library, but all I get is the following error message: "A connection attempt failed because the connected party did not properly
respond after a period of time, or established connection failed because connect
ed host has failed to respond 17.172.238.209:2195"
Why Is That?
Your provider may not allow to go out using port 2195.