linux - 具有非阻塞套接字的 Kqueue/epoll (FreeBSD/Linux):写入/发送/发送后何时可以释放缓冲内存?
问题描述
我有使用 kqueue/epoll (FreeBSD/Linux) 的非阻塞套接字(TCP 或 UPD 套接字)。当我想将字节传输到另一端时,我可以使用 write/send/sendto。它们每个都使用 char* 缓冲区进行传输,但我不明白在调用 write/send/sendto 后何时必须释放缓冲区内存。
- 如果 write/send/sendto 返回接受的字节数并且这个数字等于缓冲区大小,我可以立即释放缓冲区内存是否正确?或者我必须等待 EVFILT_WRITE (kqueue) 或 EPOLLOUT (Linux) 事件来释放缓冲区内存?
- 如果 write/send/sendto 返回接受的字节数并且这个数字不等于缓冲区大小,我只能立即释放接受的字节,我必须等待 EVFILT_WRITE (kqueue) 或 EPOLLOUT (Linux) 事件继续传输不接受的字节和下一个字节?或者我必须等待 EVFILT_WRITE (kqueue) 或 EPOLLOUT (Linux) 事件来释放缓冲区内存并传输下一个字节?
- 如果 write/send/send 是否返回 EAGAIN (kqueue) 或 EAGAIN || EWOULDBLOCK (Linux),我无法释放缓冲区内存,我必须等待 EVFILT_WRITE (kqueue) 或 EPOLLOUT (Linux) 事件来重新传输相同的字节?
解决方案
尽管您使用的是非阻塞套接字,但 write/send/sendto 调用仍然是同步的。这意味着您可以在缓冲区告诉您调用成功后立即释放它。
1.是的
当 write/send/sendto 返回完整的缓冲区大小时,表示缓冲区的全部内容已复制到套接字发送缓冲区,您可以立即释放缓冲区。
2.是的
当 write/send/sendto 返回部分大小时,您应该等待下一个可写事件发送剩余字节。
3.是的
EAGAIN 或 EWOULDBLOCK 表示写入非阻塞套接字时写入缓冲区已满。您应该再次发送这些字节。
推荐阅读
- google-bigquery - BigQuery 选择语句别名在 where 子句中不起作用
- android - 对话占据整个屏幕
- environment-variables - 局部变量实现
- r - Apache Lounge 服务器没有响应 Windows 机器上的 rpy2 包
- angularjs - facebook登录没有收到响应,没有显示错误
- cmake - CMake ExternalProject_Add 每次都会重建
- java - 如何在rest api post方法中获取实体作为参数?
- spring - 春季启动:路径参数为空
- php - 使用“list”函数时的PHP未定义偏移量消息
- vuetify.js - 数据表填充的项目不如预期