8

接続しているクライアントの IP とポートを出力するサーバーを実行する必要があるinetd のクローンを作成しています。

ソケット記述子でSTDIN上書きするので、これを行うための最初の解決策は、必要な情報を含む構造を回復することでした。ただし、これをで行うと、すべてのビットが 0 に設定された空の構造体が返されます。STDOUTsockaddr_ingetsockname()

私のアプローチの何が問題なのか、何か考えはありますか? IP/ポートを回復するために使用できる他の方法はありますか?

ありがとう

4

3 に答える 3

11

R ..が指摘したように、を使用する必要がありますgetpeername。その関数とgetsocknameストリーム ポインター ( ) ではなく、最初の引数としてファイル記述子を取りますFILE *。標準入力のファイル記述子を取得するために使用します (または定数でfileno(stdin)あるため、 にハードコードします)。STDIN_FILENO

getsocknameまた、 andの最後の引数は、定数ではなくgetpeernameへのポインタである必要があり、TCP/IP には a を使用する必要があります。socklen_tsockaddr_in

struct sockaddr_in peeraddr;
socklen_t peeraddrlen = sizeof(peeraddr);
getpeername(STDIN_FILENO, &peeraddr, &peeraddrlen);

ここで完全な例を参照してください。

于 2010-11-15T16:00:39.370 に答える
3

を使用しgetpeernameます。あなたの問題はgetsockname、ソケットの自分の(ローカル)側の情報を返すことだと思います。これはおそらく0.0.0.0にバインドされています(つまり、任意のインターフェイスからの接続を受け入れることができます)。

編集:私はあなたの実際のバグがコードを読んでいるのを見つけたと思います。この行は間違っています:

getsockname(stdin, &addr, sizeof(addr));

getsocknameandgetpeername関数は、3番目の引数として(ポインター)を取り、。ではありsocklen_t *ませsize_t。のプロトタイプにヘッダーを含めるのを忘れない限り、コンパイラはこの間違いについて通知するはずですgetsockname。また、すでに述べたように、stdin正しくありません。試す:

socklen_t len = sizeof addr;
getpeername(0, &addr, &len);

または(C99のみ):

getpeername(0, &addr, (socklen_t[1]){sizeof addr});

戻り値も確認する必要があります。そうした場合、エラーが返されていることがわかります。

于 2010-11-15T15:57:24.317 に答える
2

リモート クライアントにこれらの情報が必要な場合は、getpeername()を呼び出す必要があります。

于 2010-11-15T15:59:12.207 に答える