Client connected to a Server, how to auto restart the TCP socket after failiure? - sockets

We are using a Delphi 10.4 application on a Windows 10 PC. This PC is a Client connected to a Server by a SOCKET connection. How can it auto restart the TCP socket after a failure?
A TIdTCPClient (Indy component) is installed. If the connection failed (when server is switches OFF of a certain time), than communication is not restarting automatically after restarting the Server.
It seems that the Socket connection is blocked or removed after a timeout. Can you explain how this works, and how I can automatically restart the socket?
Closing and reopening the socket did not help.
How should I kill the socket?
I tried to close and reopen the socket and to free it. But no effect.

Indy uses sockets that operate in blocking mode exclusively. On the client side, there is no event when a connection to a server is lost. The only way to detect that condition is to perform timely read/write operations on the socket and catch any errors that may be raised. It can take a long time for the OS to timeout a dead connection, so you should configure the client's own ReadTimeout as needed.
Once you do detect an error, you can simply close and reopen the client.
However, there is a small caveat. When Indy reads bytes from a socket, they are placed in the connection's InputBuffer until your application code reads them from the connection. After a disconnect occurs, if there are any bytes unread in the InputBuffer, Indy considers the connection to still be "alive", giving you a chance to finish reading from it until the InputBuffer is exhausted. So, if you just close and reopen the connection without clearing the InputBuffer, you may get an "already connected" error, for instance. So, just make sure to Clear() the InputBuffer before reopening the connection again.

use a try-except block to catch any exceptions that occur when the socket is in use. Then, in the except block, you can close the socket and create a new one to replace it.
for example:
procedure TForm1.Button1Click(Sender: TObject);
var
Socket: TClientSocket;
begin
Socket := TClientSocket.Create(nil);
try
Socket.Host := '127.0.0.1';
Socket.Port := 8080;
Socket.Open;
// use the socket here
except
on E: Exception do
begin
Socket.Free;
Socket := TClientSocket.Create(nil);
// try again
end;
end;
end;

Related

what should the server do when a conneceted client was force killed the process which both using tcp socket?

while using net and stream socket, after client connect server, what should the server do when a conneceted client was force killed the process which both using tcp socket?
does the server know when a connected client was force killed the process?
The server knows when a client socket gets closed, which it implicitly does when the process owning the socket gets killed. The server does not get the reason why the socket gets closed though.
So there is no way for the server to react specifically at a socket close due to process killed. The server can only react to a socket closed at a time when the server does not expect the socket to get closed. How the server should react to this depends on the specific use case, i.e. there is no universal behavior.

In Client, Unix stream socket is still in CONNECTED state even though server has closed the connection

We have an unix domain stream socket connection between client process -server process. When server is terminated, it is closing its connected sockets and its listening socket.
Sometimes, In client side, Socket is still in CONNECTED state (using netstat -anp | grep . Also, in client side, when recv() is called, it returns EAGAIN errno. This behavior is observed only SOMETIMES. But, not able to understand how this is possible.
If someone can explain how it is possible, then it would be really helpful.
Are you explicitly closing the connection?
If the server code is abruptly terminated without closing all connections, the operating system will still see this connection as active because the sever hasn't had time to clean up. The method to do this depends on the language used.

epoll_wait missing EPOLLIN events on a TCP socket fd

On the server side: I am using epoll_wait to monitor the possible read IO on a TCP socket.
On the client side: I have a single threaded app to write to the socket that's connected to the server.
The problem is, sometimes epoll_wait doesn't recognize there is new IO to read even after a new message is sent from the client. (I confirmed the message is indeed received by the server using wireshark) So the client is hanging waiting on the response from server. BUT: if I kill the client connection, epoll_wait does get notified!
Originally I am using EPOLLET and thought it would be a problem. But this issue still exists after removing EPOLLET.
Is there any tool that I can use to debug this? (e.g, outside of server process, to confirm that there is IO on the server socket queue but epoll_wait doesn't process it?) Any thought or guidance on how to debug this would be appreciated.

Why is one endpoint of this TCP connection sending a packet with the RST flag?

I'm writing an application that attempts to do the following:
create a TCP server listening on an available port
create a TCP socket that connects to the server
have the server socket write data to the client
have the server socket close its end of the connection
have the client write a message to the server
Here's where the problem lies. When I attempt to run the application, the TCP exchange goes like this:
The first three packets establish the three-way handshake, and the fourth and fifth packets are the transmission of the data written by the server and its acknowledgement.
As expected, the server socket sends a packet with the FIN flag set to indicate that it is closing its end of the connection. The client acknowledges this and then attempts to write its data to the socket. The server immediately sends an RST packet, terminating the connection prematurely.
Why does this happen?
Note: the above capture was done on Windows 8.1.
The sender cannot send data after a [FIN]. Such an action will result in the receiver issuing an [RST].
The FIN probably indicates that the server has fully closed the connection in both directions. In this case if it receives any further data on the connection it will issue an RST. This suggests an application protocol error on your part. If the server sends a reply and then closes the socket, the client can't send anything else via that connection.
Possibly you need your server to call shutdown() with SHUT_WR and then read something else from the client before closing the socket. Or possibly you're just doing it wrong.

What does "connection reset by peer" mean?

What is the meaning of the "connection reset by peer" error on a TCP connection? Is it a fatal error or just a notification or related to the network failure?
It's fatal. The remote server has sent you a RST packet, which indicates an immediate dropping of the connection, rather than the usual handshake. This bypasses the normal half-closed state transition. I like this description:
"Connection reset by peer" is the TCP/IP equivalent of slamming the phone back on the hook. It's more polite than merely not replying, leaving one hanging. But it's not the FIN-ACK expected of the truly polite TCP/IP converseur.
This means that a TCP RST was received and the connection is now closed. This occurs when a packet is sent from your end of the connection but the other end does not recognize the connection; it will send back a packet with the RST bit set in order to forcibly close the connection.
This can happen if the other side crashes and then comes back up or if it calls close() on the socket while there is data from you in transit, and is an indication to you that some of the data that you previously sent may not have been received.
It is up to you whether that is an error; if the information you were sending was only for the benefit of the remote client then it may not matter that any final data may have been lost. However you should close the socket and free up any other resources associated with the connection.
one of the reasons for seeing this error and having trouble connecting to the server is that you enabled the firewall in the UNIX machine and forgot to add a rule to accept ssh connection. search in your WPS provider and you will find a way to connect to you machine and add this rules:
ufw allow ssh && ufw allow 22