我可以在connect()调用之后但在建立TCP连接之前将()写入套接字吗?

时间:2016-10-16 21:53:38

标签: sockets tcp

我的实验表明,我可以在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并重试写入。但我同意,这是一种肮脏无用的方法。

1 个答案:

答案 0 :(得分:3)

我可以在connect()调用之后但在建立TCP连接之前将()写入套接字吗?

当然,你可以。它很可能会失败。

根据POSIX specification of write()

  

[ECONNRESET]

     

尝试在未连接的套接字上进行写入。

根据Linux man page for write()

  

<强> EDESTADDRREQ

     

fd指的是对等地址所具有的数据报套接字   未使用connect(2)设置。

如果TCP连接尚未完成,则write()呼叫将失败。