4

学校でのプログラミング プロジェクトでは、tcp プロトコルと udp プロトコルを使用して、基本的なクライアント/サーバーのセットアップを設計する必要があります。C ソケット ライブラリの read() と write() を使用して、TCP が動作するようになりました。「信頼できる UDP」システムを作成する必要があります。例えば:

「サーバーが長さメッセージを受信すると、そのバイト数が送信されるまで最大500ミリ秒待機します。正しいバイト数を受信すると、文字「ACK」を含む文字列で応答します(一般的な省略形)タイムアウト期間の終わりまでに正しいバイト数を受信しない場合、サーバーはあきらめて、黙って終了します。」

sendto() および recvfrom() 関数をセットアップしましたが、2 番目のメッセージが送信されるまで 500 ミリ秒しか待機しないようにタイムアウト機能を実行する方法がわかりません。また、「ACK」を受信せず、長さの msg + msg を数回再送信しない場合は、後でクライアント側でそれを行う必要があります。タイムアウトを行うにはどうすればよいですか?

4

2 に答える 2

5

プログラムに次の関数を追加して、recvfrom関数を直接使用する代わりに使用してください。

次のfunctiongには、recvfrom関数と同じ入力パラメーター+最後のタイムアウト入力パラメーターがあります

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>

int timeout_recvfrom (int sock, char *buf, int *length, struct sockaddr_in *connection, int timeoutinseconds)
{
    fd_set socks;
    struct timeval t;
    FD_ZERO(&socks);
    FD_SET(sock, &socks);
    t.tv_sec = timeoutinseconds;
    if (select(sock + 1, &socks, NULL, NULL, &t) &&
        recvfrom(sock, buf, *length, 0, (struct sockaddr *)connection, length)!=-1)
        {
        return 1;
        }
    else
        return 0;
}
于 2012-10-03T17:29:12.990 に答える
4

select または poll を使用しない代替方法は、ソケット オプション SO_RCVTIMEO および SO_SNDTIMEO を使用することです。

tv.tv_sec = 10; /* seconds */
tv.tv_usec = 0;

if(setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0)
        printf("Cannot Set SO_SNDTIMEO for socket\n");

if(setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
        printf("Cannot Set SO_RCVTIMEO for socket\n");

SO_RCVTIMEO および SO_SNDTIMEO ソケット オプション

読み取りまたは書き込みを行う単一のソケットがある場合は、これがより適切なオプションです。複数のソケットを使用していて、データを完全に送受信したソケットを使用したい場合は、おそらく select の方が適切です。

于 2012-10-04T05:49:01.190 に答える