0

I/O ノンブロッキングでサーバーを C で書こうとしています。周りを見回すと、I/O ノンブロッキングが問題を解決できることに気付きました。Beej ガイドを読んで、クライアントからのデータを処理するためのタイムアウトを設定する recvtimeout 関数を実装しました。この問題を回避するにはselectを使用する必要があると言われましたが、recvtimeout関数ですでに使用しています。

int Server::recvtimeout(int s, char *buf, int len, int timeout)
    {

    //Check if non-blocking
    fcntl(s, F_SETFL, O_NONBLOCK);
int flags = fcntl(s, F_GETFD);
if ((flags & O_NONBLOCK) == O_NONBLOCK) {
  fprintf(stderr, "nonblocking active");
}
else {
  fprintf(stderr, "nonblocking not active");
}
    //End check

fd_set fds;
int n;
struct timeval tv;
// set up the file descriptor set
FD_ZERO(&fds);
FD_SET(s, &fds);
// set up the struct timeval for the timeout
tv.tv_sec = timeout;
tv.tv_usec = 0;
// wait until timeout or data received
n = select(s+1, &fds, NULL, NULL, &tv);
if (n == 0){
    return -2; // timeout!
}
if (n == -1){
    return -1; // error
}
// data must be here, so do a normal recv()
return recv(s, buf, len, 0);
    }

そのため、 NONBLOCK が設定されているかどうかを示すコードを追加しましたが、nonblocking activeを読み取ったことはないため、私のコードでは非ブロッキングはアクティブではありません。これを有効にするためにコードを変更するにはどうすればよいですか?

問題は、クライアントから文字列を読み取り、次のようなコードがある場合です。

        char headerstring[512];
    memset(headerstring,0,512);
    if(this->recvtimeout(client_fd,headerstring,sizeof(headerstring),10) < 0){
        close(client_fd);
    }

すべて正常に動作しますが、トランザクション中に接続を閉じるフラッダーにより、サーバーがダウンします。私はtry-catchと他のことを試しました...しかし何もしませんでした。

4

2 に答える 2

1

ソケットをノンブロッキングに設定する通常の方法は次のとおりです。

  int x;
  x=fcntl(s,F_GETFL,0);
  fcntl(s,F_SETFL,x | O_NONBLOCK);

コードでは、次を使用してフラグを取得しています

int flags = fcntl(s, F_GETFD);

一方、あなたは次のようにする必要があります

  x=fcntl(s,F_GETFL,0);

そのため、ソケットでノンブロッキングが実際に有効になっている可能性があります。

于 2012-05-29T16:35:09.997 に答える
0

いくつかのことがあります:

  1. select()電話後:

    if(n < 0) continue;
    if(FD_ISSET(s, &fds)) { //check if Socket ready for reading
       FD_CLR(s, &fds);  // Clear for next time
       // call recv()
    }
    
  2. 次のように、ソケットを非ブロッキングとして設定します。

    /* set socket as non-blocking */
    int x = fcntl(s, F_GETFL, 0);
    fcntl(s, F_SETFL, x | O_NONBLOCK);
    
于 2012-05-30T06:29:04.583 に答える