0

スレッドでselect()を使用してデータグラムソケットを監視していますが、スレッドが開始する前にデータがソケットに送信されない限り、select()は引き続き0を返します。

私は少しCとC++を混ぜています。スレッドを開始するメソッドは次のとおりです。

bool RelayStart() {
    sock_recv = socket(AF_INET, SOCK_DGRAM, 0);
    memset(&addr_recv, 0, sizeof(addr_recv));
    addr_recv.sin_family = AF_INET;
    addr_recv.sin_port = htons(18902);
    addr_recv.sin_addr.s_addr = htonl(INADDR_ANY);
    bind(sock_recv, (struct sockaddr*) &addr_recv, sizeof(addr_recv));

    isRelayingPackets = true;

    NSS::Thread::start(VIDEO_SEND_THREAD_ID);

    return true;
}

スレッドを停止するメソッド:

bool RelayStop() {
    isSendingVideo = false;
    NSS::Thread::stop();
    close(sock_recv);
    return true;
}

そして、メソッドはスレッドで実行されます。

void Run() {

    fd_set read_fds;
    int select_return;
    struct timeval select_timeout;

    FD_ZERO(&read_fds);
    FD_SET(sock_recv, &read_fds);

    while (isRelayingPackets) {

        select_timeout.tv_sec = 1;
        select_timeout.tv_usec = 0;

        select_return = select(sock_recv + 1, &read_fds, NULL, NULL, &select_timeout);
        if (select_return > 0 && FD_ISSET(sock_recv, &read_fds)) {
            // ...
        }
    }
}

問題は、RelayStart()が呼び出される前にUDPパケットをポート18902に送信しているプロセスがない場合、select()は常に0を返すことです。したがって、たとえば、スレッドを再起動せずに送信者を再起動することはできません(正しい順序で。)

送信者が最初に開始されている限り、すべてが正常に機能しているようです。

4

2 に答える 2

4

Runスレッドは一度だけ構築しread_fdsます。

select呼び出しは更新read_fdsされ、データの準備ができていないすべての記述子のすべてのビットがクリアされ、以前に設定されていてデータの準備ができている記述子のすべてのビットが設定されます。

したがって、記述子にデータの準備ができておらず、select呼び出しがタイムアウトした (そして 0 を返した) 場合、すべてのビットread_fdsがクリアされます。同じすべてゼロのビット マスクを渡してさらに呼び出すと、ファイル記述子はスキャンされません。

ループ内の各トリップで読み取りセットを再構築できます。

while (isRelayingPackets) {
    FD_ZERO(&read_fds);
    FD_SET(sock_recv, &read_fds);
    ...
}

または、ビットセットのコピーで補助変数を使用します。

while (isRelayingPackets) {
    fd_set select_arg = read_fds;
    ... same as before but use &select_arg ...
}

(または、もちろん、selectいくつかの方法でより使いやすい非インターフェースがあります。)

于 2012-04-21T07:44:22.060 に答える
0

どのように動作することを期待していましたか?のポイントはselect()、データを読み取ることができるようになるまでタイムアウトまでスリープすることです。この場合、1秒後にタイムアウトし、0を返します。おそらく、ストリームの開始前にタイムアウトを実際に望まないのでしょうか。

于 2012-04-20T22:38:37.820 に答える