In SuperWebSocket i use the config property IdleSessionTimeOut to delete sessions that are Idle but what is the meaning of KeepAliveTime?
In networking, Keep Alive usually refers to the period of time between "heart beat" messages that the client / server will send to each other to very that the connection is still open and alive. If the message fails to send the sender knows that the receiver has disconnected.
Keepalive at Wikipedia
Related
I'd like to provide my TCP/IP client class with a CheckConnection function so that I can check if something wrong has happened (my own client disconnected, server disconnected, server stuck up,...).
I have something like that:
bool isConnectionActive = false;
if (Client.Poll(100000, SelectMode.SelectWrite) == true)
isConnectionActive = true;
based on what MSDN says:
SelectWrite: true, if processing a Connect(EndPoint), and the connection has succeeded; -or- true if data can be sent; otherwise, returns false.
The point is that, testing this with simple server application, I am getting always true from CheckConnection, even if server-listener has been closed and even if server-application has been shutdown; that's weird, because I expect in those cases that both no connection is being processed (already connected minutes ago) and no data can be sent.
I have already implemented a similar connection check on server side using a combination of Poll with SelectRead and Available and it seems working properly; so now, should I write something similar also on client side? is the SelectWrite approach correct (but I'm using it improperly)?
There are lots of things you can check but none of them are assured to give you the result you are looking for. Even the implementation you have on the server will not work 100% of the time. I guarantee it will fail one day.
There are FIN packets, which should be sent from the client to the server, and vice versa when a connection is closed, but there is no guarantee that these will be delivered, or even processed.
This is generally known as the TCP Half Open problem.
Closing a TCP Socket is a mutually agreed process, you generally have a messaging protocol which tells the other end that it's closing, or you have some predefined set of instructions and you close after that.
The only reliable way to 100% detect if a remote socket is closed is to send some data to it. Only if you get an error back will you know if the socket has closed.
Some applications which don't send a lot of data implement a keep-alive protocol, they simply send/receive a few bytes every minute, so they know that the remote endpoint is present.
You can technically have two servers that are in a connected state and haven't sent data to each other for 10 years. Each end continues to believe that the other end is there until one try's to send some data and finds out it isn't.
I have a problem with sockets. This:
When client-thread ends, server trying to read, and its freezes, because socket is not closed. Thread dont close it, when its over. Its problem exist, if i using thread, but if i using two independents projects, i have no problem (exception throws, and i can catch it).
I cant use timeout, and i must correct continue server-work, when client dont close socket.
Sorry for my bad eng.
As far as I know, there is no way for TCP server (listener) to find out whether data from client are not coming because it has died/quit or is just inactive. This is not .NET's defficiency, it is how TCP works. The way I deal with it is:
1. Create a timer in my client that periodically sends signal "I am alive" to the server. For example, I just send 1 unusual ASCII character '∩' (code 239).
2. In TCP listener: use NetworkStream.Read(...) method that allows to specify timeout. If timeout expires, the server disposes the old NetworkStream instance and creates new one on the same TCP port. If the server receives "I am alive" signal from client, it keeps listening.
By the way, the property TcpClient.Connected is useless for detecting on server side whether client still uses the socket. The method only returns true if last Read action returned something. So, if client is alive and just silent, the TcpClient.Connected becomes false.
Close client when you want the connection to be closed (at the end of Client).
Better yet, use using for all disposable resources such as both clients and the listener.
I have a TCP socket based client server system.
Everything works fine but when network is disconnected form client end and reconnect it again i get automatically SocketError.ConnectionReset send form client and regarding this command the socket is closed in the server side. this is also fine.
but when i look in to the client side it shows the socket is still connected with server. (regarding socket is still connected with server [It does not happen every time], sometime it shows disconnected and some times shows connected)
Does it make sense that "server get a SocketError.ConnectionReset from
client end but client is still connected"?
So i want to know what is the possible reasons of SocketError.ConnectionReset and how to handle such type of problem i have mentioned?
Again i say, Everything is working fine in normal environment (e.g if i exit the client it is disconnected the socket same for the server)
Thanks in advance.
EDIT:
Here is the code in the client side. actually it's a timer that tick every 3 second through programs lifetime and check if Socket is connected or not if its disconnected then it tries to reconnect again through a new socket instance
private void timerSocket_Tick(object sender, EventArgs e)
{
try
{
if (sck == null || !sck.Connected)
{
ConnectToServer();
}
}
catch (Exception ex)
{
RPLog.WriteDebugLog("Exception occcured at: "+ System.Reflection.MethodBase.GetCurrentMethod().ToString()+"Message: "+ex.Message);
}
}
In normal situation (without network disconnect/reconnect) if TCP server get a
SocketError.ConnectionReset form any client, in the client side i see
clients socket is disconnected and it tries to reconnect it again
through the code shown. but when situation happen explained earlier,
server gets a SocketError.ConnectionReset but client shows it still
connected. though the TCP server shows the reset command is send form the exact client
side.
There are several causes but the most common is that you have written to a connection that has already been closed but he other end. In other words, an application protocol error. When it happens you have no choice but to close the socket, it is dead. However you can fix the underlying cause.
When discussing a TCP/IP issue like this, you must mention the network details between the client and the server.
When one side says the connection is reset, it simply means that on the wire a RST packet appears. But to know who sends the RST packet and why, you must utilize network packet captures (by using Wireshark and any other similar tools),
https://en.wikipedia.org/wiki/Transmission_Control_Protocol
You won't easily find out the cause at .NET Framework level.
The problem with using Socket.Connected as you are is that it only gives you the connected state as at the last Send or Receive operation. i.e. It will not tell you that the socket has disconnected unless you first try to send some data to it or receive data from it.
From MSDN description of the Socket.Connected property:
Gets a value that indicates whether a Socket is connected to a remote host as of the last Send or Receive operation.
So in your example, if the socket was functioning correctly when you last sent or received any data from it, the timerSocket_Tick() method would never call ConnectToServer(), even if the socket was now not connected.
how to handle such type of problem i have mentioned?
Close the socket and initiate a new connection.
I tried creating a poison message scenario in the following manner.
1- Created a message queue on a server (transactional queue).
2- Created a receiver app that handles incoming messages on that server.
3- Created a client app located on a client machine which sends messages to that server with the specific name for the queue.
4- I used the sender client app with the following code (C# 4.0 framework):
System.Messaging.Message mm = new System.Messaging.Message("Some msg");
mm.TimeToBeReceived = new TimeSpan(0, 0, 50);
mm.TimeToReachQueue = new TimeSpan(0, 0, 30);
mm.UseDeadLetterQueue = true;
mq.Send(mm);
So this is setting the timeout to reach queue to 30 seconds.
First test worked fine. Message went through and was received by the server app.
My second test, I disconnected my ethernet cable, then did another send from the client machine.
I can see in the message queue on the client machine that the message is waiting to be sent ("Waiting for connection"). My problem is that when it goes beyond the 30 sec (or 50sec too), the message never goes in the Dead-letter queue on the client machine.
Why is it so ? ... I was expecting it to go there some it timed-out.
Tested on Windows 7 (client) / Windows server 2008 r2 (server)
Your question is a few days old already. Did you find out anything?
My interpretation of your scenario would be that the unplugged cable is the key.
In the scenario John describes, there is an existing connection and the receiver could not process the message correctly within the set time limit.
In you scenario, however, the receiving endpoint never gets the chance to process the message, so the timeout can never occur. As you said, the state of the message is Waiting for connection. A message that was never sent cannot logically have a timeout to reach its destination.
Just ask yourself, how many resources Windows/ MSMQ would unneccessaryly sacrifice - and how often - to check MessageQueues for how-many conditions if the queues is essentially inactive? There might be a lot of queues with a lot of messages on a system.
The behavior I would expect is that if you plug the network cable back in and the connection is re-established that then, only when it is needed, your poison message wil be checked for the timeout and eventually moved to the DeadLetter queue.
You might want to check this scenario out - or did you already check it out the meantime?
I run my application on a network and in some cases the client lost connection to the server. After this time, when I wanted to send a message to the server I receive the following error: Operation not allowed on non-connected sockets (something like this).
I thought to create an event for object type TcpClient and when tcp_obj.Connected = false to call a function to discontinue execution of the current code. How could I do this?
Or giving me other suggestios.
Thanks.
I know at least from socket programming in Java that when a client loses connection to the server, the server does not and can not know about it. You need a heartbeat of some sort to detect the early disconnection.
We often use a heartbeat in our client/server applications to detect early disconnections and log them on the server. This way the server can close the associated socket and release the connection back to the pool.
Simply send a command to the client periodically and wait for a response. If no response is garnered within a timeout assume disconnect and close streams.
I would simply first check your connection object to ensure you are connected, prior to attempting to send the message. Also make sure that you are putting your send-logic inside of a try-catch, so that if you do happen to get disconnected mid transmission, you'll be able to resume without blowing your application apart.
Psuedo-Code:
private void SendMessage(string message, Socket socket)
{
if(socket.connectionState = States.Connected)
{
try{
// Attempt to Send
}
catch(SocketException Ex)
{
// Disconenct, Additional Cleanup Etc.
}
}
}
If you are in C#, prior to your connection state changing, you will have a socket disconnected event fire, prior to your connection state changing. Make sure you tie this event up as soon as your socket connects.
Can we know why you use TCP sockets? Is for calling a tcp device o server code?
I recommend you if is for calling a .net server app use Windows Communication Foudation. It is simple to expose services by net.tcp, http, etc.
Regards,
Actually this is a very old problem,
If I understand your question correctly you need a way to know whether you're application is still connected to the server or vice versa.
If so then a workaround is to have a UDP connection just to check the connectivity (overhead I know, but its much better then polling on Connected state), you could check just before you send you're data.
Since UDP is not Connection oriented you don't need to be connected when you send the data