Ich versuche, einen blockierenden Socket für das Timeout einzurichten, nachdem 16 ms versucht wurde, recvfrom() an einem Port auszuführen. Plattform ist Windows. Ich habe mir unzählige Beispiele online angesehen und es scheint wirklich einfach zu sein, ich kann es einfach nicht zum Laufen bringen. Jede Hilfe wäre willkommen!
#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 ist nicht sehr portabel – welche Plattform verwenden Sie?
– Messstab
1. Dezember 2009 um 7:17 Uhr
Sie möchten wahrscheinlich die verwenden
select
Funktion– Laura
1. Dezember 2009 um 9:37 Uhr
Hey danke! Ja, ich habe mir Select angeschaut und es zum Laufen gebracht!
– Cory Carlson
1. Dezember 2009 um 22:15 Uhr
Hinweis für zukünftige Leser: 1600 Mikrosekunden sind nicht gleich 16 ms.
– Ben Voigt
9. Februar 2018 um 23:05 Uhr
Die winsoc2-Dokumentation von Windows besagt, dass SO_RCVTIMEO ein DWORD in Millisekunden ist. Corys letzter Versuch war richtig. Ich bin mir nicht sicher, warum es nicht funktioniert, vielleicht der reinterpret_cast. Verwenden Sie stattdessen… (const char *)&ms.
– Gabe Halsmer
20. Februar 2018 um 0:48 Uhr