I have a tcp server that writes in winforms and a client in android. I connect devices to a wirless network then I disconnect server from this network. However client continue to listen server for a while then it closes its socket. How can I tell client to close socket when server is disconnected from network?
The reason it happens (if I understand the problem correctly) is that there is not inherent way to know that a connection has been closed, unless you try to send a package. So in your client, if you try to send an empty package over the connection, it will immediately report if the connection has been closed.
This is the reason that Heartbeats exist, and you can configure your socket to use them, or you can have your client periodically (or when needed) attempting to send an empty package and report the status of the connection.
There is an excellent article on CodeProject about this, see here.
Related
I am working on a project where we use signalr to communicate with client. I got the case where client is connected to the server and he is using VPN.
Whenever he lost internet connection he obviously lost connection to hub, but from server side is looking like the connection is still active and OnDisconnectedAsync method is not triggered (half-open websocket?). When he reconnect he is connecting to hub with new connection with different connectionId and old connection is still hanging waiting to be closed.
My question is can i somehow close this connection from server side?
I implemented ping/pong functionality which are sending messages on websocket to client and waiting for response and i want to close this connection if i dont get any message back from client after 30 seconds.
Have you perhaps overwritten some timeout methods?
Take a look at this article from Microsoft: https://learn.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/handling-connection-lifetime-events#timeoutkeepalive
It explains the lifetime of a connection and timeout functionality. Maybe this helps.
Good luck!
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.
I'm writing a c# application and I have some forms in which users can insert Ip address and port of TCP Listeners that are in other hosts.
So I would check if there is a tcp listener before to continue with the programm.
I don't want to use connect because I don't want to connect to these servers in the same time in witch I perform the control.
So for example
There is a listener
TcpListener server=new TcpListener(IP,Port);
server.start();
In the client application user insert Ip and port of many listeners that I will put in a list so:
//User insert ip and port
// PERFORM check: is there a listener at this ip and port?
than put in a list of available servers.
You cannot do this in a general way. It is not possible to determine whether there is a server socket listening at the remote endpoint, not on your local machine, without actually trying to connect.
Note that this is a variation on the "file exists?" problem, and has the same general answer: don't do that.
Even if you could confirm the presence of a remote server prior to a connection attempt, it doesn't matter because the server could stop working between the time you check for it, and the time you actually try to connect.
So you have to handle the scenario where you attempt to connect to a server and fail anyway. Finding out in advance doesn't make things easier on you, and it doesn't really help the user very much either.
If you really want to validate the user's input, you can in fact go ahead and connect to the server, and then immediately disconnect (with graceful closure...i.e. call Socket.Shutdown(SocketShutdown.Send) and wait for a 0-byte receive to complete before you actually close/dispose the Socket instance).
But personally, I'd just accept the user's input and then if later it turns out to be invalid, let them know when you actually find out that it is.
I am trying to poll a connection from a client connected to my server.
When you use poll you need to give it a socket connection but on the server's side the socket is bound to it's own IP address and a specific port. Making another socket to connect on the same port but with the client's IP address won't work since you can't have multiple connections on the same socket.
I am just wondering what would be a good way to constantly be checking if a client is still connected to the server and also when it disconnects?
I was thinking some sort of timeout check or something. I just wanted to know if there was any generic or proper way of achieving this.
I have tried Socket.Poll but it does not seem to achieve what I want.
To restate my question, how do you check if a client is connected on the server side using TCP sockets in C#?
socket.Receive will just return 0.
From MSDN
If you are using a connection-oriented Socket, the Receive method will read as much data as is available, up to the size of the buffer. If the remote host shuts down the Socket connection with the Shutdown method, and all available data has been received, the Receive method will complete immediately and return zero bytes.
There is also Connected property in the Socket class if you need.
There are two kinds of sockets: For listening and for connections. If a client has connected you must have an instance of Socket that is associated with that connection.
Use this socket to periodically send data and receive and acknowledgement back. This is the only way to make 100% sure that the connection is still open.
Especially the Connected property cannot be used to detect a lost connection because if the network cable is unplugged neither of the two parties is notified in any way. The property can't be accurate by principle.
I'm working on a C# WebSocket server (currently supported by https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-17).
The server is working with the Socket object of the .NET for the server to listen and for each client to send and receive messages.
I built a web client that connect to the server, It can connect successfully and i can send messages between clients.
Everything is working great!
Now, if i'm connecting to the server and leave the client for a while without sending messages, the server throwing an exception that says:
Int32 Send(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags):An
existing connection was forcibly closed by the remote host.
The exception, as you can see is from the Send method of the client socket in the server, this is looks very wired because i didn't sent any data from the client and no one sending data to this client back so how can it be that the Send method can throw an exception and why this exception is thrown?
It's called a timeout!
WebSockets are just a wrapper around TCP/IP raw sockets (Socket class in .NET) - which timeout if nothing is sent, and nothing is keeping the connection alive.
AFAIK currently the WebSocket API isn't very well defined as far as how to keep the connection alive. I was experiencing the same and had to just switch over to using a ping (empty message) to keep the connection alive (I'm using the Microsoft sockets implementation).
If you're reinventing the wheel for a non final spec, just remember that you'll have to keep reinventing it every time the spec changes. I specifically chose to use the Microsoft sockets preview so that when it's released I'm pretty much not going to have to change any code. I don't run in IIS - I run as a console app and it's working mostly great so far but I have very very few users.
Note: The problem i was having that led me to find this question was if I send 10 messages without receiving a reply then the connection is closed. I'm still looking into why this is - whether its a bug / feature of WebSockets or a feature of the Socket class. it's possible I'm hitting a 65kb limit but my messages are small and I don't think that's why. Just be aware of this when testing whatever you're working on becasue it gives the same error you got.
I assume that you have exclude the usage of different protocols between the servers and the clients (silly assumption, but you never know).
If your code reaches the Send method without a prior Receive from the client, then it's obvious that something is wrong with the server code. Use trace and/or log to get more information even for abc's like entering wait to receive, receiving, received, exiting receiving etc.