我的实验表明,我可以在connect()
调用之后写入非阻塞套接字,但尚未建立TCP连接,并且在连接发生(异步)后,对等方正确接收写入的数据。 Linux / FreeBSD上有保证吗?我的意思是,write()
会返回> 0何时连接仍在进行中?或许我很幸运,在connect()
和write()
电话之间成功建立了TCP连接?
实验代码:
int fd = socket (PF_INET, SOCK_STREAM, 0);
fcntl(fd, F_SETFL, O_NONBLOCK)
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(_ip_port.port);
addr.sin_addr.s_addr = htonl(_ip_port.ipv4);
int res = connect(fd, (struct sockaddr*)&addr, sizeof(addr));
// HERE: res == -1, errno == 115 (EINPROGRESS)
int r = ::write(fd, "TEST", 4);
// HERE: r == 4
P.S。
我在单个线程中处理多个侦听和连接套接字(传入和传出连接),并通过epoll进行管理。通常,当我想创建新的传出连接时,我会调用非阻塞connect()
并等待EPOLLOUT
(epoll事件),然后write()
我的数据。但我注意到我可以在EPOLLOUT
之前开始写作并获得适当的结果。我可以相信这种方法,还是应该使用我的旧时尚方法?
P.P.S。
我使用延迟时间为170毫秒的远程主机重复了我的实验并得到了不同的结果:write()
(在connect()
之后)与errno == EAGAIN
一起返回-1。所以,是的,我的第一个实验不公平(连接到快速本地主机),但我仍然认为write()
"旁边的" connect()
可以使用:如果write()
返回-1和EAGAIN,我等待EPOLLOUT
并重试写入。但我同意,这是一种肮脏无用的方法。
答案 0 :(得分:3)
我可以在connect()调用之后但在建立TCP连接之前将()写入套接字吗?
当然,你可以。它很可能会失败。
根据POSIX specification of write()
:
[ECONNRESET]
尝试在未连接的套接字上进行写入。
<强> EDESTADDRREQ 强>
fd指的是对等地址所具有的数据报套接字 未使用
connect(2)
设置。
如果TCP连接尚未完成,则write()
呼叫将失败。