2

新しい日、新しい問題。どういうわけか、ほぼ毎日ここで質問をしていることに気づきました。これまでのサポートに感謝します。select4 つのファイル記述子から読み取るように を実装しましたが、1 つしか読み取れません。

C プログラムが実行されている 2 番目のマシンに 4 つのポートすべてでパケットを送信するテスト アプリケーションがあります。

data_packet to port[13501]
data_packet to port[13502]
data_packet to port[13503]
data_packet to port[13504]
data_packet to port[13501]

等々...

I can seeを使用tcpdumpすると、テスト アプリケーションが正しく動作していることがわかります。

08:02:26.391843 IP 10.1.1.2.2000 > 10.1.1.40.13501: UDP, length: 28
08:02:27.391794 IP 10.1.1.2.2000 > 10.1.1.40.13502: UDP, length: 28
08:02:28.391820 IP 10.1.1.2.2000 > 10.1.1.40.13503: UDP, length: 28
08:02:29.391918 IP 10.1.1.2.2000 > 10.1.1.40.13504: UDP, length: 28

しかし、私のアプリケーションは 1 つの FD (ソケット) から読み取るだけです。最初に、使用可能なすべてのファイル記述子を .xml ファイル内に表示しますfd_set

thread 1 started, pc_packet_receiver 
thread 2 started, pc_packet_sender 
sock_fd[9]
sock_fd[10]
sock_fd[11]
sock_fd[12]

received on sock_fd[12] on ETH0 on port 13503
received on sock_fd[12] on ETH0 on port 13503
received on sock_fd[12] on ETH0 on port 13503
received on sock_fd[12] on ETH0 on port 13503
[ctrlC] sockets closed, threads stopped...

周りの実装はselect次のようになります。

    FD_SET(sock_fd[i], &read_fds);
    fdmax = sock_fd[i];
}

for(i = 0; i < 4; i++) {
    printf("sock_fd[%d]\n",sock_fd[i]);
}

while(keepRunning) {

    bzero(&incoming_msg, MAX_PAYLOAD_LEN);
    bzero(&outgoing_msg, MAX_PAYLOAD_LEN);
    bzero(&peer, peer_len);

    readsocks = select(fdmax+1, &read_fds, NULL, NULL, NULL);

    if (readsocks < 0) {
        perror("select");
        exit(EXIT_FAILURE);
    } else if (readsocks == 0) {
        printf("nothing to read from\n");
        continue;
    }

    for(i = 0; i < 4; i++) {

        if(FD_ISSET(sock_fd[i], &read_fds)) {

            in_msg_len = recvfrom(sock_fd[i],
                incoming_msg,
                MAX_PAYLOAD_LEN,
                0,
                (struct sockaddr *) &client_addr,
                &sock_len_client);

            if (in_msg_len < 0) {
                perror("failed to receive data\n");
                exit(EXIT_FAILURE);
            }

            strncpy(outgoing_msg, incoming_msg, in_msg_len);

            if(getsockname(sock_fd[i], &peer, &peer_len) < 0) {
                perror("getsockname() failed");
                return (-1);
            }

            receiving_eth_port = (int)ntohs(peer.sin_port);

#if DBG_OUTPUT
            printf("received on sock_fd[%d] on ETH0 on port %d\n",   sock_fd[i], receiving_eth_port);
#endif

どうすればselectすべてのソケットから読み取ることができますか...?

4

1 に答える 1

3

select()あなたのread_fds

への最初の呼び出しの後、select()fdread_fdsビットが 1 つしか設定されていない可能性があるため、残りのすべてのループでこのファイル記述子のみをチェックしています。

read_fds解決策は、 を呼び出す前に毎回再構築することselect()です。これは面倒に聞こえるかもしれませんが、 を扱うときの一般的な方法select()です。

于 2012-05-24T08:54:01.853 に答える