2

サーバーがtcpポートでリッスンしています。着信接続がある場合、 を使用accept()して子プロセスを使用および生成しfork()ます。クライアント/子プロセスは、接続からいくつかのデータを読み取り、パイプを介してサーバーに送り返します。この後、接続を閉じたいと思います。私はクライアントプロセスから使用しようとしましshutdown()close()が、あまり運がありませんでした。

shutdown()両方の結果を確認しましたが、どちらclose()も 0 を返します。どうやら問題なく実行されているようです。shutdown()との両方close()が実行された後、サーバーsigchldは子プロセスから を受け取ります。これは一般的に処理されていますが、信号を受信する前に接続を閉じたいと思います。これを行う方法に関する提案は大歓迎です。

余談close()ですが、サーバー/クライアント プログラム全体で不要なファイル記述子とソケットを閉じるために使用されていますが、これらが実際に閉じられているかどうかはわかりません。

以下に 2 つのコード スニペットを示します。まず、プログラムのサーバー部分のaccept()andです。fork()

if ((client_s = accept(s, &info.addr, &addrlen)) == -1) {
    //Error handling
}
if ((info.pid = fork()) == -1) {
    //More error handling
}
else if (info.pid == 0) {
    //Closing all unneeded file descriptors

    // Set default signal handler for SIGCHLD
    signal(SIGCHLD, SIG_DFL);

    _exit(clientStatus_main(client_s, info_pipes[1]));
}
else {
    //Adding client to list of clients and closing some file descriptors.
    close(client_s);
}

最後に、関数 clientStatus_main からのコード スニペット:

//Signal handling
signal(SIGINT, client_sighandler);
signal(SIGTERM, client_sighandler);
signal(SIGKILL, client_sighandler);
signal(SIGHUP, client_sighandler);
signal(SIGCHLD, SIG_DFL);

//Read data from socket
read(socket, &status_packet.type, iLength)
//Do data handling and write back to server
write(info_pipe, &status_packet, status_packet.len)

//Close down socket
res = shutdown(socket, SHUT_RDWR);
addlog(LOG_INFO, "Result of shutdown: %i\n", res); //Write to log
res = close(socket);
addlog(LOG_INFO, "Result of close: %i\n", res);
return (iCount > 0 ? 0 : -1);

良いアイデアはありますか?

*編集:親プロセスからやろうとしたコメントを読んだ後close(client_s)、問題は解決しませんでした。わかりやすくするために、この行もコード スニペットに追加しました。

4

2 に答える 2

1

関連する 3 つのプロセスがあります。

クライアント: 親のリッスン ソケットに接続します。

: ソケットをリッスンし、接続を受け入れて子に渡すサーバー プロセス。

child : 確立された接続を介してクライアントと通信するサーバー プロセス。

確立された接続は と の間the childにのみ存在しthe clientます。The parentどちらの側からもクライアント ソケットが閉じられたことを検出する方法がありません。

が接続を閉じて終了していることを通知the parentするには、信号をthe childキャッチするか、たとえば質問で言及されているを介してにメッセージを送信するかの 2 つの方法があります。SIGCHLDthe childthe parentpipe

于 2012-11-13T13:00:31.997 に答える
0

close()これはちょっと恥ずかしいですが、結局、問題はなかったようshutdown()です。Klas Lindbäck によるコメントと回答を見て考えさせられ、少し実験したところSIGCHLD、子プロセスと同時にクライアントが実際に接続を閉じたため、 が送信されたことがわかりました。

したがって、私のソリューションは、Klas Lindbäck の提案に触発されたものです。子プロセスは前述のパイプを介してプロセス ID を送信し、親プロセスはSIGCHLDこのプロセスからの送信を安全に無視/ブロックできるようになりました。

于 2012-11-14T09:08:29.930 に答える