【发布时间】:2010-12-21 22:06:19
【问题描述】:
我正在尝试将阻塞套接字设置为在端口上尝试 recvfrom() 16 毫秒后超时。平台是Windows。我在网上看了很多例子,看起来很简单,我似乎无法让它工作。任何帮助将不胜感激!
#include <winsock2.h>
#include <string>
#pragma comment(lib, "ws2_32.lib")
#define PORT_NUM 8001
int main(void)
{
std::string localIP;
sockaddr_in localAddr;
sockaddr_in remoteAddr;
hostent* localhost;
char buffer[1024];
WSADATA wsData;
int result = WSAStartup(MAKEWORD(2,2), &wsData); // winsock version 2
localhost = gethostbyname("");
localIP = inet_ntoa(*(in_addr*)*localhost->h_addr_list);
localAddr.sin_family = AF_INET;
localAddr.sin_port = htons(PORT_NUM); // Set Port Number
localAddr.sin_addr.s_addr = inet_addr(localIP.c_str()); // Set IP Address
int mHandle = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0);
if(mHandle == INVALID_SOCKET)
return 1;
if(bind(mHandle, (SOCKADDR*)&localAddr, sizeof(localAddr)) == SOCKET_ERROR)
return 1;
timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 1600;
// Set Timeout for recv call
if(setsockopt(mHandle, SOL_SOCKET, SO_RCVTIMEO,
reinterpret_cast<char*>(&tv), sizeof(timeval)))
return 1;
int length = sizeof(remoteAddr);
// <-- Blocks here forever
recvfrom(mHandle, buffer, 1024, 0, (SOCKADDR*)&remoteAddr, &length);
return 0;
}
/* I've also tried passing the time like so:
int ms = 16;
if(setsockopt(mHandle, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<char*>(&ms), sizeof(int)))
return 1; */
【问题讨论】:
-
SO_RCVTIMEO 不是很便携 - 您使用的是什么平台?
-
你可能想使用
select函数 -
嘿,谢谢!是的,我研究了 select 并让它工作!
-
未来读者请注意:1600 微秒不等于 16 毫秒。
-
Window 的 winsoc2 文档指出 SO_RCVTIMEO 是一个 DWORD,以毫秒为单位。科里的最后一次尝试是正确的。我不确定为什么它不起作用,也许是 reinterpret_cast。相反,使用... (const char *)&ms。
标签: c networking sockets network-programming