Sockets 什么导致ENOTCONN错误?
我目前正在维护一些web服务器软件,我需要执行很多I/O操作。在套接字上使用Sockets 什么导致ENOTCONN错误?,sockets,Sockets,我目前正在维护一些web服务器软件,我需要执行很多I/O操作。在套接字上使用read()、write()、close()和shutdown()调用时,有时可能会引发ENOTCONN错误。这个错误到底意味着什么?触发它的条件是什么?我似乎永远无法在本地复制它,但有些用户可以 现在,当由close()和shutdown()提出时,我只是忽略了ENOTCONN,因为它看起来无害,但我不能完全确定 编辑: 我绝对确信connect()调用成功。我检查它的返回值 ENOTCONN通常由close()和s
read()
、write()
、close()
和shutdown()
调用时,有时可能会引发ENOTCONN
错误。这个错误到底意味着什么?触发它的条件是什么?我似乎永远无法在本地复制它,但有些用户可以
现在,当由close()
和shutdown()
提出时,我只是忽略了ENOTCONN
,因为它看起来无害,但我不能完全确定
编辑:
- 我绝对确信
调用成功。我检查它的返回值connect()
通常由ENOTCONN
和close()
引发。我很少看到shutdown()
和read()
提升write()
ENOTCONN
从:如果你确信你已经正确地连接了,<代码> EntOnnc>代码>很有可能是因为你在请求的中间,或者在请求中间的连接下降时,<代码> FD 被关闭在你的终端(也许在另一个线程中)。< /P>
在任何情况下,这意味着插座未连接。去把那个插座清理干净。它死了。在其上调用
close()
或shutdown()
没有问题。如果您确定TCP连接的您一侧没有任何东西正在关闭连接,那么在我看来,远程端正在关闭连接
ENOTCONN
,正如其他人所指出的,只是表示套接字未连接。这并不一定意味着连接失败。套接字很可能以前已经连接过,只是在调用时没有连接到导致ENOTCONN
这不同于:
:连接的另一端发送了一个TCP重置数据包。如果另一端拒绝连接,或不承认已连接,以及其他情况,则可能发生这种情况ECONNRESET
:这通常只适用于ETIMEDOUT
。如果连接尝试在系统相关的时间内未成功,则可能发生这种情况connect
EPIPE
有时可以由一些与套接字相关的系统调用在与ENOTCONN
大致相同的条件下返回。例如,在某些系统上,EPIPE
和ENOTCONN
在通过send
返回时是同义的
虽然shutdown
返回ENOTCONN
并不罕见,但由于该函数应该会断开TCP连接,因此我会惊讶地看到关闭
返回ENOTCONN
。它真的不应该这样做
最后,正如dwc所提到的,
EBADF
不应该应用于您的场景中,除非您尝试对已经关闭的文件描述符执行某些操作。断开套接字连接(即TCP连接已断开)与关闭与该套接字关联的文件描述符不同。我认为会返回ENOTCONN,因为shutdown()不应返回EconReset或其他更准确的错误
认为对方“刚刚”关闭了连接是错误的。在TCP级别上,另一方只能半关闭连接(或中止连接)。如果两侧都关闭()(或关闭()),则连接通常完全关闭。如果双方都这么做,shutdown()实际上对双方都成功
问题是shutdown()在普通(半)关闭连接时没有成功,无论是作为第一个关闭连接还是作为第二个关闭连接从POSIX docs for shutdown()中列出的错误来看,ENOTCONN是最不合适的,因为其他错误表明传递给shutdown()的参数存在问题(或处理请求的本地资源问题)
发生了什么事?如今,双方之间的某个NAT设备可能已经放弃了关联,并作为一种反应发送重置数据包。重设连接在IPv4中非常常见,您可以在代码中的任何地方找到它们,甚至在shutdown()中伪装为ENOTCONN
一个编码错误也可能是原因。例如,在非阻塞套接字上,connect()可以返回0而不指示连接是否成功。这是因为,在关闭()套接字时,套接字的缓冲区中有数据等待传递给已关闭()或关闭()其接收套接字的远程方。 我还没有完全理解套接字是如何工作的,我是一个noob,我甚至没有找到实现这个“关机”功能的文件,但是看到整个套接字几乎没有用户手册,我开始尝试所有的可能性,直到在“受控”环境中出错。可能是其他原因,但经过多次尝试后,我终于接受了以下解释:
- 如果在远程端关闭连接后发送数据,则当您关闭()时,会出现错误李>
- 如果您在远程端关闭连接之前发送了数据,但在另一端没有收到(),您可以关闭()一次,下次尝试关闭()时,您会收到错误李>
- 如果您没有发送任何数据,您可以随时关机,只要远程端不关机();一旦远程端有shutdown(),如果您尝试shutdown()而套接字已经shutdown(),则会出现错误