sockets - 我可以在 connect() 调用之后、TCP 连接建立之前对套接字进行 write() 操作吗?

标签 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

附注 我在单线程中处理多个监听和连接套接字(传入和传出连接)并通过 epoll 管理它们。通常,当我想创建新的传出连接时,我会调用非阻塞 connect() 并等待 EPOLLOUT (epoll 事件),然后 write() 我的数据。但我注意到我可以在 EPOLLOUT 之前开始写入并获得适当的结果。我可以相信这种方法还是应该使用我的旧时尚方法?

P.P.S。 我在延迟 170 毫秒的远程主机上重复了我的实验,并得到了不同的结果:write()(就在 connect() 之后)返回 -1,errno = = EAGAIN。所以,是的,我的第一个实验并不公平(连接到快速本地主机),但我仍然认为可以使用 connect() 旁边的“write()” :如果 write() 返回 -1 和 EAGAIN,我会等待 EPOLLOUT 并重试写入。但我同意,这是肮脏且无用的方法。

最佳答案

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

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

根据 POSIX specification of write() :

[ECONNRESET]

A write was attempted on a socket that is not connected.

根据 Linux man page for write() :

EDESTADDRREQ

fd refers to a datagram socket for which a peer address has not been set using connect(2).

如果 TCP 连接尚未完成,您的 write() 调用将会失败。

关于sockets - 我可以在 connect() 调用之后、TCP 连接建立之前对套接字进行 write() 操作吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40075878/

相关文章:

linux - 我可以监控 Linux 套接字缓冲区满度吗?

python - 在 Anaconda Python 中缺少 socket.AF_BLUETOOTH?

java - "java.net.BindException: Can' t 分配请求地址 "on client' s 端

c - 代理需要非阻塞套接字吗?

c++ - TCP:如何生成 seq/ack 号?

使用 c connect() 连接被拒绝?

java - 在android中的Socket通信中写入十六进制字符串

java - JAVA 上的 TCP 套接字 - 任何字节 >= 128 被接收为 65533

python - 检测套接字挂断而不发送或接收?

Node.js 服务每天卡死一次