【发布时间】:2012-08-21 07:38:58
【问题描述】:
我正在编写一个 C 函数来检查来自客户端的套接字连接是否可用。我使用带有 MSG_PEEK 的“recv”函数来不改变输入缓冲区。
但是,当客户端关闭套接字连接时,'recv' 应该返回 -1,但事实并非如此。客户端关闭后,下面函数中的'recv'一直返回0。
char is_avail(int connection) {
char buffer;
int result = recv(connection,&buffer,1,MSG_PEEK);
if (result<0)
return 0;
else
return 1;
}
这件事有什么理由吗?我还想将 MSG_PEEK 与 MSG_WAITALL 结合起来。我试过了:
recv(connection,&buffer,1,MSG_PEEK|MSG_WAITALL);
但是没有生效。
【问题讨论】:
-
检查来自客户端的套接字连接是否可用你在调用
listen的套接字上调用recv? -
不要使用
MSG_WAITALL,因为它会阻塞直到它可以满足您的请求。所以它会一直阻塞,直到有数据要读取(或在你的情况下偷看),理论上这可能是永远的。 -
@JoachimPileborg 实际上,recv 已经默认执行此操作,除非套接字设置为“非阻塞”。无论如何,MSG_WAITALL 在这种情况下毫无意义,因为它会等到可以读取 1 个字节...这等于它在没有 MSG_WAITALL 的情况下等待的字节数。
-
MSG_PEEK 和一般的 isAvailable 从套接字检查是一个坏主意。它在 Winsock 程序员跛脚名单中赢得了一席之地——因为它天生不可靠。不要使用 PEEK,只需立即将所有数据复制到自己的缓冲区。
-
@kert 很老的评论.. 但是,我目前正在考虑将协议从固定大小的缓冲区更改为动态大小的消息,并且会对 MSG_PEEK 的任何优点/缺点感兴趣,你知道任何资源吗关于这个话题?