GNU/Linux >> Linux の 問題 >  >> Linux

接続が開いているか閉じているかを確認しますか? (Linux の C)

シグナルを処理しない write() の代わりに send() を使用します:

bzero(buffer, MAX_SIZE_BUFFER);
n = read(sockfd, buffer, MAX_SIZE_BUFFER - 1);
printf("after read%d\n", n);
if (n <= 0)
{
    break;
}
n2 = send(newsockfd, buffer, n, MSG_NOSIGNAL);
if (n2 == -1)
{
    close(sockfd);
    close(newsockfd);
    return;
}
if (n2 != n)
{
    break;
}

エラーが発生したのはかなり後になるまでわからないことが多いため、ソケット プログラミングはややこしい場合があります。

たとえば、書き込んでいるマシンが異常終了した場合、(内部 OS バッファに書き込むことができたので) write 呼び出しは成功するかもしれませんが、close 呼び出し中に失敗するだけです。

ソケットがアクティブであることを確認するアプリケーション層の方法 (つまり、メッセージを送信し、一定期間内に応答を要求する) がない限り、知る方法はありません。標準プロトコルを使用している場合、エラーを処理するための何かがすでに存在している可能性があります。

したがって、短い答えは、ソケットに触れるほぼすべての呼び出し (読み取り、書き込み、閉じるなど) からのエラー リターンをチェックする必要があるということです。


ソケットに書き込めるかどうかを確認する方法は、驚くべきことに、ソケットに書き込んでみることです:-)

ソケットが閉じられている場合は、-1 が返されます write からの戻りコード errno を調べることができます 問題が何であったかを確認してください。

ソケットがまだ有効であるが、現時点でデータを書き込むことができない場合、 write 0 を返します。read call も同様に動作し、-1 を返します。 問題があれば。

基本的に write 用 :

  • -1 が返ってきたら 、問題が発生しました。errno を確認してください 回復可能か致命的かを確認します。
  • 0 が返ってきたら 、その場合、現時点では何も書くことができません (ネットワークのバックログまたはその他の問題である可能性がありますが、(まだ) 致命的ではないことは間違いありません)。
  • 必要な値よりも低い値が得られた場合は、some のデータが送信されました。次のサイクルで残りを送信できるように、ポインターを調整します。 しない 正の戻り値は、ブロック全体が送信されたことを意味すると想定します。
  • 送信しようとしたバイト数と同じ数が返された場合、バッファ全体が配信のために受け入れられています.
  • 送信を要求した以上の返信があった場合は、辛辣なコメントを添えてカーネル開発者にメールを送ってください。 Linus 達はそれを気に入るはずです :-)

更新: caf がコメントで指摘したように、シグナル処理を考慮するのを忘れていました。壊れたパイプ信号または write を無視する必要があります そのシグナルを上げることで内部的に失敗します。

以下を挿入することでこれを行うことができます:

struct sigaction new_actn, old_actn;
new_actn.sa_handler = SIG_IGN;
sigemptyset (&new_actn.sa_mask);
new_actn.sa_flags = 0;
sigaction (SIGPIPE, &new_actn, &old_actn);

ソケット機能を使い始める前に。次に使用できます:

sigaction (SIGPIPE, &old_actn, NULL);

以前のシグナル処理を復元します。


Linux
  1. LinuxでNetstatを使用してリスニング/オープンポートを確認する方法

  2. リモートLinuxシステムで開いているポートを確認する方法

  3. Linux サーバーでポートが開いているか閉じているかを確認しますか?

  1. Linux で特定のプロセスのオープン FD 制限を確認する

  2. CでのLinuxクリップボードの読み取り/書き込み

  3. ユーザー空間のLinuxブロックデバイスドライバーを作成するには?

  1. Linux OS で開かれているすべてのソケットをチェックする

  2. LinuxでO_APPENDモードで開くを使用して、Cでファイルに追加する方法は?

  3. Linux でソケット接続のアップタイムを確認する方法