使用 connect() API连接到目标IP时遇到问题。 connect() API会将-1
和错误号码返回为operation in progress
。我是否在建立连接之前过早检查返回代码?请参阅以下代码段:
struct sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(9190);
const char * remoteIp = 10.10.20.86;
rc = inet_pton(AF_INET,remoteIp, &servAddr.sin_addr);
if (rc == -1 || errno == EAFNOSUPPORT)
{
return 0;
}
rc = connect(fd, (sockaddr*)&servAddr, sizeof(servAddr));
if ( rc < 0) // this is where it fails. rc is -1.
{
log("connect failure with [%s]",strerror(errno));
print_sock_connect_error();
}
我在这里有两个问题:
10.10.20.86:9190
正在等待连接,一旦收到连接,它就会将ack发送回源。我看到tcp建立了 - ACK,SYN / ACK和ACK到目的地 - 在 pcap 中,但仍然无法弄清楚为什么它返回-1
有错误。那么我是否在连接建立完成之前检查了rc? sysctl net.ipv4.tcp_syn_retries
设为6. 答案 0 :(得分:1)
- 10.10.20.86:9190正在等待连接,一旦收到连接,它就会将ack发送回源。我看到tcp建立了 - ACK,SYN / ACK和ACK到目的地 - 在pcap中但仍然无法弄清楚为什么它返回-1并出错。那么我是否在连接建立完成之前检查了rc?
醇>
你当然是。您立即connect()
返回检查它。当你将套接字置于非阻塞模式时,那时三路线握手就不可能完成了。
sysctl net.ipv4.tcp_syn_retries设置为6.
不相关。
- 上面的代码有什么问题吗?
醇>
只是它没有意义。
如果您希望在connect()
返回之前他的连接完成或失败,请不要使用非阻止模式。
如果您想使用非阻止模式,则必须使用select()
告知您何时完成连接尝试。选择套接字变为可写。 (这并不一定意味着 变得可写:这意味着连接尝试已经完成,结果你可以通过getsockopt()/SO_ERROR
发现。)
答案 1 :(得分:0)
我是否在连接建立完成之前检查了rc?
是的,你是。连接设置期间的TCP乒乓不是必须完成的。
上面的代码有什么问题吗?
嗯,是的,无论是处理EINPROGRESS
情况的方式,还是使用非阻塞套接字进行连接。
来自connect()
的Linux documentation:
<强> EINPROGRESS 强>
套接字是非阻塞的,连接不能 马上完成。可以选择(2)或民意调查(2) 通过选择用于写入的套接字来完成。后 select(2)表示可写性,使用getsockopt(2)来读取 SOL_SOCKET级别的SO_ERROR选项确定是否 connect()成功完成(SO_ERROR为零)或 失败(SO_ERROR是通常的错误代码之一 列在这里,解释失败的原因)。