web-dev-qa-db-ja.com

UDPソケットセットタイムアウト

UDPソケットに100ミリ秒のタイムアウトを設定しようとしています。私はCを使用しています。以下にコードの関連部分を投稿しました。これがタイムアウトにならない理由はわかりませんが、セグメントを受け取らないとハングします。これはbind()メソッドを使用してバインドされていないソケットでのみ機能しますか?

#define TIMEOUT_MS      100     /* Seconds between retransmits */

if ((rcv_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
    DieWithError("socket() failed");

if ((rcv_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
    DieWithError("socket() failed");

//set timer for recv_socket
static int timeout = TIMEOUT_MS;
setsockopt(rcv_sock, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));

if(recvfrom(rcv_sock, ackBuffer,sizeof(ackBuffer), 0,
       (struct sockaddr *) &servAddr2, &fromSize) < 0){
    //timeout reached
    printf("Timout reached. Resending segment %d\n", seq_num);
    num_timeouts++;
}
29
rharrison33

SO_RCVTIMEOオプションは、struct timevalで定義されているsys/time.hを想定しています。これは、渡されるような整数ではありません。 timeval structには、秒のフィールドとマイクロ秒のフィールドがあります。タイムアウトを100ミリ秒に設定するには、次の手順を実行する必要があります。

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 100000;
if (setsockopt(rcv_sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0) {
    perror("Error");
}
49
Neal

私は同じ問題を抱えています。 timeval構造体を使用して、提案されたソリューションを採用しようとしました。しかし、うまくいかなかったようです。

私はMicrosoftのドキュメントを読みましたが、時間はミリ秒数のDWORDであるはずですが、WSASocket関数を使用してソケットが作成された場合、別のこともありますdwFlagsパラメーターには、タイムアウトが適切に機能するようにWSA_FLAG_OVERLAPPED属性を設定する必要があります。それ以外の場合、タイムアウトは有効になりません。

1
user9510357