vic*_*ico 12 c++ sockets recv visual-c++
我从socket使用recv函数读取.没有可供阅读的数据时,我遇到了问题.我的程序停止了.我发现我可以使用select函数设置超时.但看起来超时会影响select函数本身,recv而select之后仍会等待不连续.
fd_set set;
struct timeval timeout;
FD_ZERO(&set); /* clear the set */
FD_SET(s, &set); /* add our file descriptor to the set */
timeout.tv_sec = SOCKET_READ_TIMEOUT_SEC;
timeout.tv_usec = 0;
int rv = select(s, &set, NULL, NULL, &timeout);
if((recv_size = recv(s , rx_tmp , bufSize ,0)) == SOCKET_ERROR)
{
...
}
Run Code Online (Sandbox Code Playgroud)
recv一些提示后如何询问函数返回?
Rem*_*eau 25
在recv()不使用的情况下自行设置超时的另一种方法select()是使用setsockopt()设置套接字的SO_RCVTIMEO选项(在支持它的平台上).
在Windows上,代码如下所示:
DWORD timeout = SOCKET_READ_TIMEOUT_SEC * 1000;
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
//...
recv_size = recv(s, rx_tmp, bufSize, 0);
if (recv_size == SOCKET_ERROR)
{
if (WSAGetLastError() != WSAETIMEDOUT)
//...
}
Run Code Online (Sandbox Code Playgroud)
在其他平台上,代码看起来像这样:
struct timeval timeout;
timeout.tv_sec = SOCKET_READ_TIMEOUT_SEC;
timeout.tv_usec = 0;
setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
//...
recv_size = recv(s, rx_tmp, bufSize, 0);
if (recv_size == -1)
{
if ((errno != EAGAIN) && (errno != EWOULDBLOCK))
//...
}
Run Code Online (Sandbox Code Playgroud)
你应该检查的返回值select.select将0在超时到期时返回,因此您应检查错误并recv仅在select返回正值时调用:
成功时,select()和pselect()返回三个返回的描述符集中包含的文件描述符的数量(即,readfds,writefds,exceptfds中设置的总位数),如果超时到期,则可能为零在有趣的事情发生之前
int rv = select(s + 1, &set, NULL, NULL, &timeout);
if (rv == SOCKET_ERROR)
{
// select error...
}
else if (rv == 0)
{
// timeout, socket does not have anything to read
}
else
{
// socket has something to read
recv_size = recv(s, rx_tmp, bufSize, 0);
if (recv_size == SOCKET_ERROR)
{
// read failed...
}
else if (recv_size == 0)
{
// peer disconnected...
}
else
{
// read successful...
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32245 次 |
| 最近记录: |