質問
私は書いています INETDのクローン クライアントのIPとポートを印刷するサーバーを実行するサーバーを実行する必要があります。
上書きすると STDIN
と STDOUT
ソケット記述子を使用して、 私の最初の解決策 これを行うことは、回復することでした sockaddr_in
必要な情報を含む構造。でこれを行う getsockname()
, ただし、すべてのビットが0に設定されている空の構造を返すことです。
私のアプローチの何が問題なのかという考えはありますか? IP/ポートの回復に使用できる他のアプローチはありますか?
ありがとう
解決
R ..が指摘したように、使用する必要があります getpeername
. 。その機能の両方と getsockname
ファイル記述子を最初の引数として取得し、ストリームポインターではありません(FILE *
)。使用する fileno(stdin)
標準入力のファイル記述子を取得する(またはハードコードに STDIN_FILENO
, 、一定であるため)。
また、最後の議論 getsockname
と getpeername
ポインターである必要があります socklen_t
, 、定数ではありません、そしてあなたは sockaddr_in
TCP/IPの場合:
struct sockaddr_in peeraddr;
socklen_t peeraddrlen = sizeof(peeraddr);
getpeername(STDIN_FILENO, &peeraddr, &peeraddrlen);
完全な例を参照してください ここ.
他のヒント
使用する getpeername
. 。あなたの問題はそれだと思います getsockname
ソケットの独自の(ローカル)側の情報を返しています。これは、おそらく0.0.0.0にバインドされています(任意のインターフェイスからの接続を受け入れることができることを意味します)。
編集: 私はあなたの実際のバグがコードを読んでいるのを見つけたと思います。この行は間違っています:
getsockname(stdin, &addr, sizeof(addr));
getsockname
と getpeername
関数はaを取ります socklen_t *
(a ポインター)彼らの3番目の議論として、 size_t
. 。コンパイラは、プロトタイプにヘッダーを含めるのを忘れていない限り、この間違いについてあなたに伝える必要があります getsockname
. 。また、すでに言われているように、 stdin
間違っている。試す:
socklen_t len = sizeof addr;
getpeername(0, &addr, &len);
または(C99のみ):
getpeername(0, &addr, (socklen_t[1]){sizeof addr});
また、返品値を確認する必要があります。もしそうなら、あなたはそれがエラーを返していることがわかります。
リモートクライアントにそれらの情報が必要な場合は、電話する必要があります getPeername().