What causes the ENOTCONN error?
I am currently maintaining some web server software and I have a lot of I / O to do. Calls read()
, write()
, close()
and shutdown()
, when used in a socket, can sometimes cause an error ENOTCONN
. What exactly does this error mean? What are the conditions that can cause this? I can never reproduce it locally, but there are users who can.
Right now, I just ignore ENOTCONN
when it climbs on close()
and shutdown()
because it seems harmless, but I'm not entirely sure.
EDIT:
- I am absolutely sure the challenge
connect()
succeeded. I am checking its return value. -
ENOTCONN
most often expressedclose()
andshutdown()
. I very rarely seenread()
, andwrite()
increasingENOTCONN
.
a source to share
If you are sure that nothing on your side of the TCP connection is closing the connection, then it sounds to me like the remote side is closing the connection.
ENOTCONN
as others have pointed out simply means that the socket is not connected. This does not necessarily mean that connect
it failed. The socket may have been connected before, it just wasn't there at the time of the call that led to ENOTCONN
.
This is different from:
-
ECONNRESET
: TCP reset packet was sent on the other end of the connection. This can happen if the other end refuses to connect, or doesn't recognize that it's already connected, among other things. -
ETIMEDOUT
: this usually only applies toconnect
. This can happen if a connection attempt is not made within the system time period.
EPIPE
may sometimes be returned by some socket-related system calls under conditions that are more or less the same as ENOTCONN
. For example, on some systems EPIPE
and ENOTCONN
are synonymous when returned send
.
Although shutdown
there is nothing to return for ENOTCONN
since this function has to break the TCP connection, I would be surprised to see close
return ENOTCONN
. It really should never be this way.
Finally, as dwc mentioned, EBADF
shouldn't be applied in your script unless you are trying to perform some operation on a file descriptor that was already close
d. Disconnecting a socket (i.e. a TCP connection) is not the same as closing the file descriptor associated with that socket.
a source to share
I believe ENOTCONN is returned because shutdown () should not return ECONNRESET or other more precise errors.
It is incorrect to assume that the other side "just" closed the connection. At the TCP level, the other side can only close the connection (or terminate it). The connection is normal, completely closed, if both sides execute shutdown () (or close ()). If both parties do this, shutdown () will indeed succeed for both of them!
The problem is that shutdown () failed to do a normal (half) close of the connection, neither the first to close it, nor the second. - Of the errors listed in the POSIX docs for shutdown (), ENOTCONN is the least inappropriate, as others indicate problems with the arguments passed to shutdown () (or local resource problems to handle the request).
So what happened? These days, a NAT device located somewhere between the two parties involved could drop the association and send RESET packets in response. RESET connections are so common for IPv4 that you get them anywhere in your code, even disguised as ENOTCONN in shutdown ().
An encoding error can also be the cause. For example, on a non-blocking socket, connect () might return 0 without indicating a successful connection.
a source to share
This is because at the moment the socket is disconnected (), you have data in the socket buffer awaiting delivery to the remote side, which has closed () or closed () its receiving socket. I don't understand how sockets work, I'm more of a noob and I didn't even manage to find files that implement this "shutdown" function, but after seeing that there is practically no user manual for all the sockets I started trying to use all the possibilities. until I get an error in a "controlled" environment. It might be something different, but after a lot of trying, this is the explanation that I agreed to:
- If you submitted data after the remote side closed the connection, you will receive an error when disconnecting ().
- If you sent data before the remote side closed the connection but did not receive it () on the other end, you can disable () once, and the next time you try to terminate (), you will get an error.
- If you didn't send any data, you can disconnect all the time if you want, unless the remote side disconnects (); as soon as the remote side disconnects (), if you try to disconnect () and the socket is already disconnected (), you will get an error.
a source to share
If you are sure that you have connected correctly, ENOTCONN
it will most likely be caused by something fd
being closed at your end (perhaps in a different thread?) While you are in the middle of a request, or by dropping a connection when you are in the middle of a request.
In any case, this means that the socket is not connected. Go and clean this outlet. He is dead. No problem with close()
or shutdown()
on the call .
a source to share