If it doesn't close in both directions, will it never close - regardless of expiration timers? - It can half-close but can the tcp connection terminate if only one initiates the close()?
In other words:
In TCP connection termination - can you close the connection fully when only the client initiates a close but the server does not.
Or can a tcp connection be closed by both ways independently?
Each peer can close the TCP connection independent from the other and the peer will simply get an EOF (e.g no more bytes) when it tries to read from the peer or get an ECONNRESET or EPIPE if it tries to write to a connection which was closed by the peer, but only if the socket is aware that the peer does not want to receive more data, see below.
Closing a connection consists actually of two parts:
Application will not send any more data: shutdown(sock,SHUT_WR). In this case the kernel will send a FIN to the peer so signalize that no more data will follow. Reading from the peer will return EOF.
Application does not want to receive more data: shutdown(sock,SHUT_RD). In this case no information will be send to the peer initially, but if data get received from the peer they will be rejected with RST.
A call of close() is thus equivalent of shutting down both sides of the connection at the same time (SHUT_RDWR).
Related
Is there a case that recv function doesn't return 0 when tcpip is disconnected physicially? There is no calling return 0. So, Tcpip is no closed. What should I do to resolve this issue?
Recv returns 0 only if TCP connection is closed explicitly by remote side.
Another cases of disconnect:
If TCP connection is explicitly broken (TCP RST or ICMP unreachable packet received) then you can get error when read from the socket.
If transit network goes down or remote host disappears then:
if timeout explicitly specified then read waits and return timeout error
if timeout is not specified then read waits maximum timeout (depends on system for Linux it is about 2 hours)
In last case you may:
Try to enable keepalive requests on socket (SO_KEEPALIVE socket options)
Do keepalive by yourself on application layer:
Send something to the peer and expect answer from it
If nothing received within timeout - close connection
In the TCP three way handshake connection procedure does the client (the one who initiated the connection) send to the server any data payload joined with the ACK packet in the third step ?
The last ACK in the TCP handshake can already contain a payload. But, this is usually not done since the application first calls connect and then will either wait for the server to reply or send its first data. Since the kernel does not know what the application will do next it will already send out the ACK within the connect so that the server knows as fast as possible that the connection is established.
Depending on your OS it might be possible to change this behavior and send the ACK together with the first data. In Linux this can be achieved by explicitly disabling quick ack before connecting:
int off = 0;
setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &off, sizeof(off));
connect(fd,...)
(Original title: "Weird TCP connection close behavior")
I am troubleshooting TCP connection process using Wireshark. Client opens connection to server (I tried two different servers), and starts receiving long stream of data. At some point in time client wants to stop and sends server [FIN, ACK] packet, but server does not stop sending data, it continues till its own full stream end, and then sends its own completion packet [FIN, PSH, ACK]. I figured it out keeping reading data from the client's socket after client sent FIN packet. Also, after client sent this FIN packet, its state is FIN_WAIT, thus waiting for FIN response from server...
Why servers do not stop sending data and respond to FIN packet with acknowledgment with FIN set?
I would expect, after client sends FIN packet, server will still send several packets which were on the fly before it received FIN, but not the whole pack of long data stream!
Edit: reading this I think that web server is stuck in stage "CLOSE-WAIT: The server waits for the application process on its end to signal that it is ready to close" (third row), and its data sending process "is done" when it flushed all contents to the socket at its end, and this process can not be terminated. Weird.
Edit1: it appears my question is a little different one. I need to totally terminate connection at client's side, so that server stops sending data, and it (server) would not go crazy about forceful termination from client's side, and aborted its data sending thread at its side being ready for next connection.
Edit2: environment is HTTP servers.
The client has only shutdown the connection for output, not closed it. So the server is fully entitled to keep sending.
If the client had closed the connection, it would issue an RST in response to any further data received, which would stop the server from sending any more, modulo buffering.
Why servers do not stop sending data and respond to FIN packet with acknowledgment with FIN set?
Why should they? The client has said it won't send another request, but that doesn't mean it isn't interested in the response to any requests it has already sent.
Most protocols, such as HTTP, specify that the server should complete the response to the current request and only then close the connection. This is not an abnormal abort, it's just a promise not to send anything else.
in a tcp program written in Linux C
I want to close a tcp connectin
I used close(sockfd)
I notice this function will initiate a FIN/ACK packet to the other peer
but if the other peer doesn't respond an ACK due to network problem or tcp sequnce number inconsistency(e.g the tcp stack of the other peer crashes)
then it seems the tcp connection can't be closed
it will always be in FIN_WAIT1 status
how to deal with this?
how to close the tcp connection in such cases?
TCP deals with it. You don't have to deal with it. You can't deal with it.
By default, this is transparently handled by the TCP implementation according to system-wide configuration parameters which are system-dependent.
This can be overridden by setting the SO_LINGER socket option using setsockopt(), in which case the call to close() blocks until the specified timeout is reached.
Edit: I should add that most of the time using SO_LINGER is only worth the hassle if the goal is to add some error handling such as logging an error message stating that possibly some data was not received by the other end.
We are facing random RST packet problem in our environments, which causes some unexpected behaviors, following image is snapshot of the tcp data generated by wireshark, which shows the problem:
Client (117.136.2.181) successfully sets up the connection with the server (192.168.40.16)
Client sends some data to the server, as well the KEEP_ALIVE signal.
Server receives the data, process it and sends the result back to client.
Server close the socket.
Server does not receive the ACK signal from client, so it re-transmits the result data as well as the FIN signal, this is automatically done by TCP protocol. However, server still does not receive the ACK signal from client.
Server sends a RST signal to client so connection is closed.
After some analysis, we think some network problem happens after step 3, so all the result data and FIN signal sent from server are not ack'd by client, but we are very confused about the RST signal sent from the server. Based on our understanding, a RST signal is sent if a half-closed socket receives some data, or if there is data in the receive queue when closes a socket. But both these seem not be the root cause of our case.
Can some one help to elaborate why this is happening?
RST usually happens when close is called on the socket without shutdown, or after a shutdown while the other party is still trying to send data (still has not replied with an FIN).
Some programming languages have a socket.close(timeout) for example .NET, that calls shutdown then close after timeout has passed.
So the client have up to timeout to finish sending and closing the connection with FIN, if it fails to do so, the connection will be forcibly closed by RST.
See https://stackoverflow.com/a/23483487/1438522 for a more thorough explanation about difference between close and shutdown.