如何将socket设置成非阻塞的,非阻塞socket与阻塞的socket在收发数据上的区别
发布日期:2021-05-08 05:59:40 浏览次数:22 分类:精选文章

本文共 1098 字,大约阅读时间需要 3 分钟。

生成socket时设置

在生成socket时,默认情况下socket是阻塞的。此外,我们可以通过设置特定选项将socket设置为非阻塞模式。

非阻塞socket配置

可以通过以下方式将socket设置为非阻塞模式:

int s = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);

使用fcntl设置

我们可以使用fcntl函数来设置socket的阻塞模式。

将socket设置为非阻塞

if ((nFlags = fcntl(nSock, F_GETFL, 0)) < 0) {
return 0;
}
nFlags |= O_NONBLOCK;
if (fcntl(nSock, F_SETFL, nFlags) < 0) {
return 0;
}

将socket设置为阻塞

if ((nFlags = fcntl(nSock, F_GETFL, 0)) < 0) {
return 0;
}
nFlags &= ~O_NONBLOCK;
if (fcntl(nSock, F_SETFL, nFlags) < 0) {
return 0;
}

非阻塞和阻塞在收发数据时的区别

TCP发送时的区别

TCP发送(即send函数)
  • 阻塞模式下,send函数会等待所有数据都被拷贝到发送缓冲区才会返回。这意味着在阻塞模式下,send函数返回值必定等于参数中发送长度。
  • 非阻塞模式下,send函数会立即返回,但它会尽可能多地拷贝数据到缓冲区。由于缓冲区可能已满,返回值可能小于发送长度。
UDP发送(即sendto函数)
  • 即使在阻塞模式下,sendto函数也不会阻塞。UDP没有真正的发送缓冲区,它仅将应用缓冲区数据拷贝到协议栈,并不涉及阻塞。
  • 非阻塞模式下,sendto函数的行为与阻塞模式下相同。

TCP接收时的区别

TCP接收(即recv函数)
  • 阻塞模式下,recv函数会阻塞,直到缓冲区中有至少一个字节才会返回。如果没有数据到来,recv函数会一直阻塞或直到超时。
  • 非阻塞模式下,recv函数不会阻塞。如果缓冲区中有任何一个字节,它会立即返回。如果没有数据,recv函数会返回错误WSAEWOULDBLOCK。
UDP接收(即recvfrom函数)
  • 阻塞模式下,recvfrom函数会阻塞,直到缓冲区中有一个完整的UDP数据包才会返回。
  • 非阻塞模式下,recvfrom函数会立即返回。如果缓冲区中有一个完整的数据包,它会返回数据包大小;如果没有数据,会返回错误WSAEWOULDBLOCK。
上一篇:优雅关闭以及如何检测对端已经关闭
下一篇:tcp粘包及如何解决

发表评论

最新留言

关注你微信了!
[***.104.42.241]2025年03月24日 09时57分08秒