我试图设置一个阻塞套接字,在尝试端口上的recvfrom()16 ms后超时.平台是Windows.我在网上看了很多例子,看起来很简单,我似乎无法让它发挥作用.任何帮助,将不胜感激!
#include#include #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 (&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 (&ms), sizeof(int))) return 1; */
Cory Carlson.. 24
我查看了select函数,并且laura说我应该这样做,让它很容易实现!谢谢!
fd_set fds ; int n ; struct timeval tv ; // Set up the file descriptor set. FD_ZERO(&fds) ; FD_SET(mHandle, &fds) ; // Set up the struct timeval for the timeout. tv.tv_sec = 10 ; tv.tv_usec = 0 ; // Wait until timeout or data received. n = select ( mHandle, &fds, NULL, NULL, &tv ) ; if ( n == 0) { printf("Timeout..\n"); return 0 ; } else if( n == -1 ) { printf("Error..\n"); return 1; } int length = sizeof(remoteAddr); recvfrom(mHandle, buffer, 1024, 0, (SOCKADDR*)&remoteAddr, &length);
joseAndresGo.. 15
我通过像下面的那样传递它来尝试它
int iTimeout = 1600; iRet = setsockopt( pSapManager->m_cSocket, SOL_SOCKET, SO_RCVTIMEO, /* reinterpret_cast(&tv), sizeof(timeval) ); */ (const char *)&iTimeout, sizeof(iTimeout) );
并运行它!
我查看了select函数,并且laura说我应该这样做,让它很容易实现!谢谢!
fd_set fds ; int n ; struct timeval tv ; // Set up the file descriptor set. FD_ZERO(&fds) ; FD_SET(mHandle, &fds) ; // Set up the struct timeval for the timeout. tv.tv_sec = 10 ; tv.tv_usec = 0 ; // Wait until timeout or data received. n = select ( mHandle, &fds, NULL, NULL, &tv ) ; if ( n == 0) { printf("Timeout..\n"); return 0 ; } else if( n == -1 ) { printf("Error..\n"); return 1; } int length = sizeof(remoteAddr); recvfrom(mHandle, buffer, 1024, 0, (SOCKADDR*)&remoteAddr, &length);
我通过像下面的那样传递它来尝试它
int iTimeout = 1600; iRet = setsockopt( pSapManager->m_cSocket, SOL_SOCKET, SO_RCVTIMEO, /* reinterpret_cast(&tv), sizeof(timeval) ); */ (const char *)&iTimeout, sizeof(iTimeout) );
并运行它!
WINDOWS:超时值是一个DWORD(以毫秒为单位),传递给setsockopt()的地址是const char*
LINUX:Timeout值是一个struct timeval,传递给setsockopt()的地址是const void*
资料来源:http://forums.codeguru.com/showthread.php?t = 353217