5

UDPメッセージを受信し、ユーザーからの入力を受け取るプログラムを作成していますが、STDINはまだselectでブロックされています。select の前に stdin fd を FD_CLR すると、プログラムは正常に実行され、stdin ソケットからデータを読み取る準備が常に整っていることを示します。タイムアウトするために timeval テレビを導入しようとしましたが、これも機能していないようです。どこかでソケットを閉じるか、そうでない場所で FD_CLR を呼び出す必要がありますか? 最終結果は非ブロッキング STDIN になるはずですが、現在はブロックされています。ありがとうございました

int
wait_for_input(){
            fd_set fds;
            int maxfd, sd, err, n;
            struct sockaddr_in addr;
            char stdbuf[BUFLEN];
            unsigned char udpbuf[BUFLEN];

            //memset(stdbuf,0x0,sizeof(stdbuf));
            memset(stdbuf,0x0,sizeof(udpbuf));

            sd = socket(AF_INET, SOCK_DGRAM, 0);

            if(sd<0) {
            printf("Failed to Open UDP socket");
            }

            addr.sin_family = AF_INET;
            addr.sin_addr.s_addr = htonl(INADDR_ANY);
            addr.sin_port = htons(host_list[0]->port);
            err = bind(sd,(struct sockaddr *) &addr,sizeof(addr));

            if(err < 0){
                            printf("ERROR: Cant bind port");

            }

                            struct timeval tv;
            while(1){
                            FD_ZERO(&fds);
                            FD_SET(STDIN_FILENO,&fds);
                            FD_SET(sd,&fds);
                            tv.tv_sec = 1;
                            tv.tv_usec = 0;
                            fflush(stdout);
                            select(sd+1,&fds,NULL,NULL,&tv);

                            // If a UDP message arrives
                            if(FD_ISSET(sd,&fds)){
                                            n = recv(sd,udpbuf,sizeof(udpbuf),0);
                                            unpack(udpbuf);
                                            recompute_my_dv();
                                            fflush(stdout);

                             }
                            //If console data is entered.
                                if(FD_ISSET(STDIN_FILENO, &fds)){
                                            fgets(stdbuf,sizeof(stdbuf),stdin);
                                            parse(stdbuf);
                                            printf("server> ");
                                            fflush(stdout);
                                            FD_CLR(STDIN_FILENO,&fds);


                             }

                     }



 return 0;
 }
4

1 に答える 1

0

FD_ISSET は、そのソケットのバッファにメッセージがある場合は 1 (または true) を返しません。指定されたファイル記述子がファイル記述子セットの一部である場合は true を返します。それが 1 つの問題です。

次は、ループを開始する必要があることです (while ループ) は、選択ステートメントの前に開始し、そこにループバックする必要があります。選択によって返された値をキャプチャする必要があります。これは、select の引数 2 (読み取り、書き込み、またはエラー) で指定したバッファー内のビット数が select によって返されるためです。そのため、read をバッファとして指定した場合、select によって返されたビット数を読み取る必要があります。

この2つが主な問題だと思います。お役に立てれば。

于 2013-05-10T14:01:12.153 に答える