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と他のことを試しました...しかし何もしませんでした。