When to close a TcpClient connection [closed] - c#

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm having trouble understanding the proper flow when a TcpListener and TcpClient communicate with each other.
I have a program that starts up a TcpListener on port 8088 and listens for TcpClient connections.
I have another program that creates a TcpClient (let's call it DataSender1) and connects to the TcpListener in the other program and sends it data.
If DataSender1 is a program that runs constantly (like a service) and pushes data to the TcpListener regularly over time, when should the TcpListener close DataSender1's connection? Should I close the connection after I receive and process each distinct message from DataSender1? Or, whenever I decide to shut down the TcpListener? Do I create a new connection each time DataSender1 is ready to send data?
I'm running into an issue in an actual application where the TcpListener aborts the connection whenever my TcpClient sends 202 messages. I have no idea why it constantly aborts on message 202.

If DataSender1 is a program that runs constantly (like a service) and pushes data to the TcpListener regularly over time, when should the TcpListener close DataSender1's connection?
Unless your communication protocol dictates that the TcpListener should close the connection, then it shouldn't close the connection at all, unless an I/O error occurs on the connection, the TcpClient has disconnected its end of the connection, or the TcpListener is being shutdown. The TcpClient should decide when to close the connection, such as when it is not going to be sending/receiving any data for awhile.
If the connection is going to sit idle for awhile, but it should still be left open for whatever reason, then the TcpClient and TcpListener should implement some kind of ping/pong messaging between them. Or, you could just enable TCP keep-alives at the transport layer.
Should I close the connection after I receive and process each distinct message from DataSender1?
There is overhead in tearing down a connection and re-establishing a new connection. So try to avoid that as much as possible. If you are sending data frequently, there is no good reason to close the connection.
For example, HTTP is a stateless protocol. So in HTTP 0.9, and in HTTP 1.0 by default, a connection is closed after a response is sent, and a new request would require a new connection. But as the Internet evolved, and WWW pages grew in complexity, and so HTTP traffic usage increased, it was found to be more efficient to leave the HTTP connections open and reuse them whenever possible (especially if SSL/TLS is used). Which is why using persistent connections is now the default behavior in HTTP 1.1.
Most other TCP-based Internet protocols depend on persistent connections to maintain user state.
If you are designing your own custom communication protocol between your TcpClient and TcpListener, then you get to decide how your connections are to be managed.
Do I create a new connection each time DataSender1 is ready to send data?
Only if it is not already connected to the TcpListener. Whether it disconnects afterwards depends on your design and architectural needs.
I'm running into an issue in an actual application where the TcpListener aborts the connection whenever my TcpClient sends 202 messages. I have no idea why it constantly aborts on message 202.
Then you likely have a bug in your TcpListener code that you need to find and fix. Which is what a debugger is meant for. Put some breakpoints in the TcpListener's code, and step through the code to see what the TcpListener does when message 202 is received.

Related

Handle RST packets as normal connection termination

I have a service that is listening and consuming TCP messages. I recently came across a device that sends TCP messages but instead of ending the connection in the regular way, e.g. using FIN, it always ends connections using RST, which on my end is seen as a connection aborted by remote host and the data in the socket queue is gone.
During my research I've come across different opinions on whether that's valid/acceptable and have seen some conclusions stating that applications need to start accepting terminations via RST instead of FIN (or both).
My question is, how? As soon as the client sends the RST packet to my server I get winsock error 10054 stating that the connection was aborted by the remote host. At my application level I don't seen to have any control over it since I just get the error at that point.
This results in two possible intermittent outcomes, depending on timing:
- Data in the queue is processed and then the connection is dropped.
- The connection is dropped before data can be processed and it is lost.
So I'm trying to do what I can to prevent these RST packets from being seen as aborts and be able to handle the data sitting in the queue consistently.

Socket remains connected after the remote computer closes it

I've already searched but didn't solve my issue.
I'm simulating a TCP network on my localhost. Server listens on a port and client connects to the server. The problem is that when I close the socket by client, the Socket.Connected remains true in the server. I need to know when clients are disconnected.
I suppose when I call Socket.Close on client app, a TCP FIN packet is sent to the server, right? But it seems like it doesn't.
Can you give me a solution?
P.S. I already called shutdown before closing, but the problem still persists.
There is no notification based way to know if a client is disconnected. That is the nature of tcp/ip communication. The usual way to know if a client is connected or not is to write data to the client connection. If you get an error, you can guess that the client is disconnected. You can streamline the heuristics by looking for specific exceptions
While I have no practical experience with socket programming in C# it seems that Socket.Close() does not send pending data and by implication doesn't send the FIN packet. (That is in my opinion a bit misleading because the Close semantics seem to differ from the Stream.Close() which calls Dispose(true) which tries to flush if possible. Correct me if I'm wrong.)
The MSDN documentation states:
For connection-oriented protocols, it is recommended that you call
Shutdown before calling the Close method. This ensures that all data
is sent and received on the connected socket before it is closed.
If you need to call Close without first calling Shutdown, you can
ensure that data queued for outgoing transmission will be sent by
setting the DontLingerSocket option to false and specifying a non-zero
time-out interval. Close will then block until this data is sent or
until the specified time-out expires. If you set DontLinger to false
and specify a zero time-out interval, Close releases the connection
and automatically discards outgoing queued data.

How to keep a TCP Socket alive and detect a disconnect?

In my C# program, I use TCP Sockets for communication.
How does the Socket know, that there is no more connection, when the other side hasn't properly called Shutdown/Close or whatever.
Like for example when Internet connection is lost.
What I learned about TCP is that it sends keep alive packets. What are the standard values for this, how frequently are they send, where can I set the interval and how can I set the disconnect timeout ( the time to wait before the connection is considerd disconnected when nothing is received )?
If a socket doesn't send or receive any data then by definition the socket is alive and open. A TCP can sit forever and so long as each end knows about it's current state it will still work.
The issue you can run into is where intermediate device (such as stateful firewall) maintains a timeout for the TCP connection that has nothing to do with the end device and the the end devices have no visibility. If after, two three or even four days, one devie wants to send data on the TCP channel, if an intermediate device fails to send it on, then and only then will the socket "disconnect".
In relation to your question about tcp-keep-alives - this is Operating System dependent.
Here's a good write up on the Windows way: https://blogs.technet.microsoft.com/nettracer/2010/06/03/things-that-you-may-want-to-know-about-tcp-keepalives/

TcpClient reconnect to an already open connection

I'm working with TcpClient to communicate with a hardware device.
The communication to the device may drop for a period of 30 seconds or so, as part of a testing process. This is fine and sometimes intended.
The problem begins when I'm sending data to the device while communication is down. Because I'm using TcpClient, I'm getting an IO exception and the connection is dropped. The connection at the device side is still open though.
How can I:
Reconnect to the open connection at the device? creating a new TcpClient will create a new connection at the device side and is unwanted...
Perhaps Make TCP retransmissions take longer then 30 seconds ?(windows 7)
Your best method is to exchange a session identifier or have some other way to track connections and have code to handle resumes. You can increase the value of your SendTimeout Property, but the receive side could still end up timiing out the connection on its end.
You cannot reopen a specific connection with TcpClient once it is closed. The only other way you might do this (raw sockets code) seems to me to be more trouble than it's worth.

How can I forcibly close a TcpListener

I have a service which communicates through tcpListener.
Problem is when the user restarts the service - an "Address already in use" exception is thrown, and the service cannot be started for a couple of minutes or so.
Is there's any way of telling the system to terminate the old connection so I can open a new one? (I can't just use random ports because there is no way for the service to notify the clients what is the port, so we must depend on a predefined port)
Set the SO_REUSEADDR socket option before binding to the listening port. It looks like the corresponding .NET code is something like:
SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
There is a reason sockets are not used for some time after they are closed.
A Socket is comprised of a 4 tuple, Source and Dest Port, Source and Dest IP.
Let's say you close a socket forcefully, while the client was busy sending data to the server.
You wait 5 seconds and re-open the server with the same Port, and the same client sends data to the same 4 tuple, the server will get packets with wrong tcp sequence numbers, and the connections will get reset.
You are shooting yourself in the foot :)
This is why connections have a time_wait status for 2-4 minutes (depending on distro) until they can be used again.
Just to be clear, i'm talking about SOCKETs and not just the listening tcp port.

Categories