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/
Related
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.
Preface:
I have an asynchronous socket server where we receive telemetry data, and when the remote devices do not send us data, we have the ability to send commands to request data. The listener and command processing are done on separate threads. The listener listens on one port, while the commands send on a different port.
My overall question is: Is it possible with C# to check if a socket is connected without having to call a "connect" method in the first place? Our customers device will establish a connection to the server and will remain connected always (unless service coverage drops or battery drains etc.). I'd like to avoid having to keep track of all the connected socket objects in memory if possible.
To be honest I'm not even sure if what I'm asking is feasible. I'd like to hear people's thoughts.
If you know the socket information, you could probably invoke GetExtendedTcpTable and get the state of the socket ("established" or not).
For an example of pinvoking this function, see:
http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/5b8eccd3-4db5-44a1-be29-534ed34a588d/
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.
I have a client server situation where the client opens a TCP socket to the server, and sometimes long periods of time will pass with no data being sent between them. I have encountered an issue where the server tries to send data to the client, and it seems to be successful, but the client never receives it, and after a few minutes, it looks like the client then gets disconnected.
Do I need to send some kind of keep alive packet every once in a while?
Edit: To note, this is with peers on the same computer. The computer is behind a NAT, that forwards a range of ports used to this computer. The client that connects with the server opens the connection via DNS. i.e. it uses the mydomain.net & port to connect.
On Windows, sockets with no data sent are a big source for trouble in many applications and must be handled correctly.
The problem is, that SO_KEEPALIVE's period can be set system-wide (otherwise, a default is useless two hours) or with the later winsock API.
Therefore, many applications do send some occasional byte of data every now and then (to be disregarded by the peer) only to make the network layer declare disconnection after ACK is not received (after all due retransmissions done by the layer and ack timeout).
Answering your question: no, the sockets do not disconnect automatically.
Yet, you must be careful with the above issue. What complicates it further is that testing this behavior is very hard. For example, if you set everything correctly and you expect to detect disconnection properly, you cannot test it by disconnecting the physical layer. This is because the NIC will sense the carrier loss and the socket layer will signal to close all application sockets that relied on it. A good way to test it is connect two computers with 3 legs and two switches in between, disconnecting the middle leg, thus preventing carrier loss but still physically disconnecting the machines.
There is a timeout built in to TCP but you can adjust it, See SendTimeout and ReciveTimeout of the Socket class, but I have a suspiciouion that is not your problem. A NAT router may also have a expiration time for TCP connections before it removes it from it's port forwarding table. If no traffic passes within the time of that timeout on the router it will block all incoming traffic (as it cleared the forwarding information from it's memory so it does not know what computer to send the traffic to), also the outgoing connection will likely have a different source port so the server may not recognize it as the same connection.
It's more secure to use Keep-alive option (SO_KEEPALIVE under linux), to prevent disconnect due to inactivity, but this may generate some extra packets.
This sample code do it under linux:
int val = 1;
....
// After creating the socket
if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *)&val, sizeof(val)))
fprintf(stderr, "setsockopt failure : %d", errno);
Regards.
TCP sockets don't automatically close at all. However TCP connections do. But if this is happening between peers in the same computer the connection should never be dropped as long as both peers exist and have their sockets open.
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.