c - 避免在不使用 O_NONBLOCK 时发送到 block

标签 c sockets unix select

我必须使用 unix 套接字(没有 O_NONBLOCK)为一个类编写一个聊天客户端-服务器,并在它们上选择异步 I/O。目前,在服务器上,我从客户端读取了1024字节,并直接处理。

例如,在消息的情况下,我将收到格式为 MSG <msg> 的命令(代表客户端发送消息),我将遍历连接的客户端的所有套接字并将消息写入它们。

这种方法确实有效,但我最近通过阅读 send 的人发现如果套接字缓冲区已满并且未在套接字上设置标志 O_NONBLOCK,它可以阻塞。

我认为当客户端由于某些原因(崩溃、窃听等)没有读取时可能会发生此问题,这对我的服务器至关重要,因为它基本上会阻塞,直到该客户端再次读取。

所以这是我的问题:

如果套接字缓冲区已满,在潜在阻塞套接字上避免 send to 阻塞的正确方法是什么?

我目前仅使用 select 来检查套接字上是否有可读取的内容,但也许我也应该使用它来查看我是否也可以在特定套接字上写入?而且,我能知道 select 返回时我可以读/写多少字节吗?例如,如果 select“告诉”我可以在此套接字上写入,我怎么知道在在此套接字上写入实际上变成阻塞之前我最多可以写入多少字节?

谢谢。

最佳答案

您可以将 setsockopt()SO_SNDTIMEO 一起使用来设置 send() 将尝试完成其工作的最长时间.

有关详细信息,请参阅 man setsockoptman 7 socket

关于c - 避免在不使用 O_NONBLOCK 时发送到 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16211428/

相关文章:

UNIX 缓冲与非缓冲 I/O

linux - 多线程环境 - 类 UNIX 环境中的 C++ 信号处理(freeBSD 和 linux)

c - 通过C中的套接字传递具有整数数组的结构

c - 如何将 16 位数字存储在两个字节的 char 数组中?

macos - 在 unix 中从 'last' 命令中获取常用用户名 - 有异常(exception)

java - 让一个 Runnable 或 Thread 只被调用一次

python - Twitch IRC 机器人不发送消息

c - 是否存在 strcmp() 返回 -1 0 和 1 以外的值的编译器和库?

c - main 函数中的参数点

c - 套接字寻址机制卡住了