tags:

views:

1335

answers:

3

I'm currently maintaining some web server software and I need to perform a lot of I/O operations. The read(), write(), close() and shutdown() calls, when used on a socket, may sometimes raise an ENOTCONN error. What exactly does this error mean? What are the conditions that would trigger it? I can never seem to reproduce it locally but there are users who can.

Right now I just ignore ENOTCONN when raised by close() and shutdown() because it seems harmless, but I'm not entirely sure.

EDIT:

  • I am absolutely sure that the connect() call succeeded. I check for its return value.
  • ENOTCONN is most often raised by close() and shutdown(). I've only very rarely seen a read() and write() raising ENOTCONN.
A: 

Transport endpoint is not connected

The socket is associated with a connection-oriented protocol and has not been connected. This is usually a programming flaw.

From: http://www.wlug.org.nz/ENOTCONN

Lennart
I know the name of the error, but what does it *mean*? What is this transport endpoint that it's referring to and how is this any different from EPIPE, ECONNRESET and ETIMEDOUT?
Hongli
I guess you just did not call connect() or did not check if connect() succeeded.
Lennart
I did, it succeeded. Users who were reporting this problem observed that the read()s and write()s work just fine, but at shutdown() and close() time it raises ENOTCONN. I cannot reproduce it locally at all, and nor do most users experience this problem.
Hongli
A: 

If you're sure you've connected properly in the first place, ENOTCONN is most likely to be caused by either the fd being closed on your end (perhaps in another thread?) while you're in the middle of a request, or by the connection dropping while you're in the middle of the request.

In any case, it means that the socket is not connected. Go ahead and clean up that socket. It's dead. No problem calling close() or shutdown() on it.

dwc
I'm pretty sure the fd is not being closed by another thread. But suppose it is, wouldn't that cause an EBADFD instead?Furthermore, it's often close() and shutdown() that raise ENOTCONN, not read() and write(). What would this mean?
Hongli
Note in my answer I specify "in the middle of a request". So you make the call, and execution switches to another process. Then the connection drops, and your process begins executing... EBADFD was not and is not true (it's a valid fd), but you're not connected. So you get ENOTCONN.
dwc
A: 

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 doesn't necessarily mean that connect failed. The socket may well have been connected previously, it just wasn't at the time of the call that resulted in ENOTCONN.

This differs from:

  • ECONNRESET: the other end of the connection sent a TCP reset packet. This can happen if the other end is refusing a connection, or doesn't acknowledge that it is already connected, among other things.
  • ETIMEDOUT: this generally applies only to connect. This can happen if the connection attempt is not successful within a system-dependent amount of time.

EPIPE can 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 by send.

While it's not unusual for shutdown to return ENOTCONN, since this function is supposed to tear down the TCP connection, I would be surprised to see close return ENOTCONN. It really should never do that.

Finally, as dwc mentioned, EBADF shouldn't apply in your scenario unless you are attempting some operation on a file descriptor that has already been closed. Having a socket get disconnected (i.e. the TCP connection has broken) is not the same as closing the file descriptor associated with that socket.

Dan Moulding