2

これが以前に尋ねられたのを見たことがありますが、うまくいく答えは見つかりませんでした。その情報を他のクライアントに転送するために、サーバーが接続されているコンピューターの明示的な IP アドレス (つまり、123.456.789.100) とポート番号を取得する必要があります。Windows 7 (Home Premium)、Visual Studio 2010 Professional で WinSock2.h を使用して、「C++ コンソール アプリケーション」を作成しています。これは TCP 接続です。これまでの私のコードは次のとおりです。

sockaddr_in* addr = new sockaddr_in;
int addrsize = sizeof(addr);
getsockname(clientSock, (sockaddr*)addr, &addrsize);
char* ip = inet_ntoa(addr->sin_addr);
int port = addr->sin_port;
printf("IP: %s ... PORT:%d\n", ip, port);

これにより、常に IP に 205.205.205.205、PORT に 52685 が毎回返されます。gethostbyname などの代替手段を試しましたが、これは機能しますが、実際の IP 自体が必要です。getsockname() の代わりに getpeername() も試しましたが、結果は同じでした。私はルーターの背後にいますが、これまで同じマシンでサーバーとクライアントの両方を使用しています。

事前にすべての助けに感謝します!

4

2 に答える 2

4

getpeername() は、使用したい関数です。

コードに表示されるいくつかのエラー:

1) ヒープに addr を割り当てています。その必要はありません。「sockaddr_in addr;」と宣言するだけです。代わりにスタック上に置き、 getpeername() 呼び出しに &addr (addr の代わりに) を渡します。

2) addrsize は、実際の sockaddr_in のサイズではなく、ポインターのサイズ (4 または 8 など) に設定されています。つまり、...

3) getsockname() はおそらく失敗していますが、あなたはそれを知りません。

4) エラーがあったかどうかを確認するために getsockname() の戻り値をチェックしていません。つまり、

5) 表示されている結果は、getsockname()/getpeername() 呼び出しの前にランダムなガベージ データが (*addr) にあったことを示しているだけです。これは、addr 構造体に何も書き込まずに呼び出しが失敗したためです。

6) ああ、もう 1 つ... addr.sin_addr への参照を ntohl() 呼び出しでラップし、addr.sin_port への参照を ntohs() 呼び出しでラップするようにしてください。リトルエンディアン (読み: Intel ベース) コンピューターで実行する場合のエンディアン形式。

于 2011-07-11T00:16:56.930 に答える
2

はい、あなたは正しかったです、それはエラーを投げていました、そして私はそれをチェックしていません. どうもありがとう、あなたの解決策はうまくいきました。私のために働いた最終的なコードは次のとおりです。

sockaddr_in addr;
int addrsize = sizeof(addr);
int result = getpeername(clientSock, (sockaddr*) &addr, &addrsize);
printf("Result = %d\n", result);
char* ip = inet_ntoa(addr.sin_addr);
int port = addr.sin_port;
printf("IP: %s ... PORT: %d\n", ip, port);

そして、それは私に正しい結果をもたらしました。私はあなたの助けに感謝します。ありがとう!

于 2011-07-11T08:13:00.900 に答える