5

ファイル記述子を使用して読み取り可能なソケットを見つけ、読み取りを続けます。何らかの理由で、ワイヤ上にデータがないソケットは読み取りを続行し、決して返されません。タイムアウト後に受信から抜け出す方法はありますか?

私はwinsockライブラリを使用しています..

4

2 に答える 2

9

http://tangentsoft.net/wskfaq/newbie.html#timeout

2.15 - Winsock 関数のタイムアウトを変更するにはどうすればよいですか?

一部のブロッキング Winsock 関数 (connect() など) には、タイムアウトが組み込まれています。この背後にある理論は、スタックだけが適切なタイムアウトを設定するために必要なすべての情報を持っているということです。しかし、スタックが使用する値が自分のアプリケーションには長すぎることに気付く人もいます。1 分以上かかる場合があります。

send() および recv() タイムアウトは、SO_SNDTIMEO および SO_RCVTIMEO setsockopt() オプションで調整できます。.

他の Winsock 関数については、ソケットを完全にブロックしないようにするのが最善の解決策です。すべてのノンブロッキング ソケット メソッドは、カスタム タイムアウトを作成する方法を提供します。

Non-blocking sockets with select() – The fifth parameter to the select() function is a timeout value.

Asynchronous sockets – Use the Windows API SetTimer().

Event objects – WSAWaitForMultipleEvents() has a timeout parameter.

Waitable Timers – Call CreateWaitableTimers() to make a waitable timer, which you can then pass to a function like WSAEventSelect() along with your sockets: if none of the sockets is signalled before the timer goes off, the blocking function will return anyway.

非同期で非ブロッキングのソケットを使用すると、タイムアウトの処理を完全に回避できる場合があることに注意してください。Winsock がビジー状態であっても、プログラムは動作し続けます。そのため、時間がかかりすぎる操作をキャンセルするか、コードでこの機能を引き継ぐのではなく、Winsock の自然なタイムアウトの期限切れをユーザーに任せることができます。

于 2011-07-20T00:19:52.557 に答える
0

あなたの問題は、バッファを埋めようとするwhileループにあります.'\ 0'のすべてのチャンクの最後のインデックスをチェックするifステートメントを入れてから、whileループを壊してください

do {
    len = rcv(s,buf,BUF_LEN,0);
    for (int i = 0; i <= len; ++i) {
        if (buf[i] >= 32 || buf[i] == '\n' || buf[i] == '\r') { //only write valid chars
            result += buf[i]; //final string
        }
    }
    if (buf[len] == '\0') { //buf[len] is the last position in the received chanks 
        break;
    }
} while (inner_result > 0);
于 2022-02-26T09:31:06.150 に答える