友
我有一个非阻塞的TCP套接字(在AIX上)。当我尝试连接()时,我得到了EINPROGRESS。我的问题是,如果我在连接完成之前调用recv(),那么(最适合的)错误代码是什么?
我看到了,如果连接失败,我调用recv(),我得到了ECONNREFUSED;意味着我收到了与我之前的connect()尝试相对应的错误。采用相同的逻辑,我应该得到recv()的EINPROGRESS。我的做法是对的吗?
如果是,这就提出了另一个问题 - 为什么这些错误代码不包含在recv()的错误代码中?
答案 0 :(得分:3)
在这种情况下我只看到了EAGAIN返回,正如您在没有数据可读的情况下所看到的那样。对于写入非连接套接字,通常会获得ENOTCONN,但我相信某些平台可能会为您提供EAGAIN。
这是一个简单的Python脚本来演示:
import socket
# Any address that does not succeed or fail right away will do
ADDR = "192.168.100.100"
PORT = 23
s = socket.socket()
s.setblocking(False)
try:
s.connect((ADDR, PORT))
except socket.error, e:
print "Connect gave us",e
try:
s.recv(1)
except socket.error, e:
print "Read gave us",e
try:
s.send("x")
except socket.error, e:
print "Write gave us",e
对我而言,它给出了: Connect给了我们(36,'正在进行中的操作') 阅读给了我们(35,'资源暂时不可用') 写给了我们(57,'套接字未连接')
分别是EINPROGRESS,EAGAIN和ENOTCONN。
答案 1 :(得分:1)
您正在使用非阻塞套接字,这非常适合返回EINPROGRESS,这表明连接建立尚未完成,这在连接页面中有记录:
EINPROGRESS
The socket is nonblocking and the connection cannot be completed immediately. It is possible to select(2) or poll(2) for completion by
selecting the socket for writing. After select(2) indicates writability, use getsockopt(2) to read the SO_ERROR option at level SOL_SOCKET
to determine whether connect() completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual error codes listed
here, explaining the reason for the failure).
因此,您需要select / pool来确保套接字是可写的,并从SO_ERROR获取错误。