0

これを簡潔に列挙するのは少し難しいかもしれませんが、ドメインと問題の初心者の理解に最善を尽くします。

最初にリンクを解除し、ソケット記述子を作成し、バインドし、リッスンし、ローカル UNIX ソケットで受け入れるストリーム サーバーの 2 つのプロセスがあります。サーバーの仕事は、接続を受け入れ、任意のデータを送信し、任意のデータを受信することです。クライアント プロセスの仕事は、初期設定を除いてサーバーと同じことをすることです。ソケット記述子を作成し、UNIX ソケットに接続します。

サーバーを起動すると、UNIX ソケットが作成されていることを確認できます。クライアントを起動するconnect()と、ファイルまたはディレクトリが存在しないか無効であることを示すエラーが表示されます。そして、はい、以前のようにUNIXソケットを見つけようとすると、ファイルはもう存在しません...

この動作を引き起こしているバグの理由や場所を知っている人はいますか?

コード スニペットが明確にするのに役立つ場合は、それらも投稿できます。

struct addrinfo * server;
int sockfd;

sockfd = socket( server->ai_family, server->ai_socktype, server->ai_protocol );

if( connect(sockfd, server->ai_addr, server->ai_addrlen) == 0 )
    return sockfd;
else
    perror("connect()");

UNIX ドメイン専用のにデータgetaddrinfoを入力するために、 の修正版を使用していることにも注意してください。addrinfo struct

4

1 に答える 1

2

サーバーの起動に続いて、クライアント システムにソケット ファイルが存在することを確認します。つまり、クライアントの接続に渡されるsun_pathフィールドで使用するファイルが存在することを確認します。struct sockaddr_unこのエントリは、サーバーで作成され、 に渡されたものと一致する必要がありますbind。またsun_family、クライアントとサーバーの両方のフィールドにAF_UNIX.

クライアントでは、ソケット ファイルの作成/削除を実行しないでください。つまり、サーバー ソケットの場所に関連するクライアント コードのどこにもリンク解除があってはなりません。

これらは、コードが正しく動作していることを確認するために従う一般的なプロセスです。サンプルのサーバー/クライアントは、古いものの依然として信頼できるBeej の UNIX IPC ガイドにあり、これはおそらく比較すべき最も単純な例です。

編集getaddrinfoコメントの議論に基づいて、カスタム呼び出しが unix ソケット ファイルの削除の原因であることが判明しました。これは、コードにhints->ai_flags & AI_PASSIVEが設定されているかどうかをチェックするサーバー側のロジックがあるためです。この場合、ソフトウェアがbind(サーバーのように) を実行していると予想されるため、ソケット ファイルのリンクを解除します。AI_PASSIVEフラグに関するロジックは RFCで体系化されており、その場合、ファイルが存在しないとバインドは失敗します。

AI_PASSIVE フラグが指定されている場合、返されたアドレス情報は、指定されたサービスの着信接続を受け入れるためのソケットのバインド (つまり、bind() の呼び出し) での使用に適している必要があります。

ただし、その段落の最後の文は次のように述べています。

nodename 引数が null でない場合、このフラグは無視されます

getaddrinfo( "/local", "/tmp/socket", hints, &server)したがって、 nodename パラメータが null ではないため、この call のケースではロジックが少し間違っているようです。

于 2012-04-10T14:15:39.617 に答える