-3

問題は解決しました。根本的な原因は、C++ 一時オブジェクトを getpeername() の sockaddr* として渡したことが原因で、getpeername() が返された後に自動的に破棄されました。

したがって、正味の結果は 0 でいっぱいでした。

私の不注意で申し訳ありません。この投稿を閉じることに投票しました。クローズするためにも投票してください。


#include <winsock2.h>
#include <windows.h>
#include <thread>

using namespace std;

void server()
{
    sockaddr_in server_addr {};
    server_addr.sin_family      = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port        = htons(1234);

    SOCKET s_listening = socket(AF_INET, SOCK_STREAM, 0);

    bind(s_listening, (sockaddr*)&server_addr, sizeof(server_addr));
    listen(s_listening, 5);

    while (true) 
    {
        auto s_new = accept(s_listening, 0, 0);

        sockaddr_in client_addr {};
        int size = sizeof(client_addr);
        auto ret = getpeername(s_new, (sockaddr*)&client_addr, &size); 
        //
        // ret is 0, which means the call to getpeername is OK. 
        // But client_addr is full of 0s rather than "127.0.0.1:4". Why?
        //
    }
}

int main()
{
    std::thread(server).detach();
    SOCKET s_client = socket(AF_INET, SOCK_STREAM, 0);

    sockaddr_in client_addr {};
    client_addr.sin_family      = AF_INET;
    client_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    client_addr.sin_port        = htons(4);

    bind(s_client, (sockaddr*)&client_addr, sizeof(client_addr));

    sockaddr_in server_addr {};
    server_addr.sin_family      = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_addr.sin_port        = htons(1234);

    connect(s_client, (sockaddr*)&server_addr, sizeof(server_addr));
    getchar();
}

コードは VC++ 2012 でコンパイルされています。ただし、関数 getpeername の呼び出しは OK を返しますが、返されたデータは間違っています (0 でいっぱい)、なぜですか?

4

1 に答える 1

3

getpeername()構造体を初期化しsockaddr_<something>ます。<something>等しい場合in、IP アドレスとポートをバイナリ形式で保持しています。

ピアの名前/アドレスおよびポートの ASCII 表現を保持する文字バッファーは保持されません。

また、値はsockaddr_inネットワーク バイト順で保持されます。

OPのソーススニペットのコメントで表現されているアドレスとポートを出力するには、次のようにします。

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

...

int sd = -1; /* init to invalid socket */

... /* get sd a proper value */

sockaddr_in sa = {0}; /* init to all zeros */
socklen_t sl = sizeof(sa);
if (getpeername(sd, (sockaddr *) &sa,  &sl))
  perror("getpeername() failed");
else
  printf("peer is: %s:%hu\n", inetntoa(sa.sinaddr), ntohs(sa.sin_port));
于 2013-02-15T07:46:34.377 に答える