getpeername()不适用于与localhost的连接

时间:2009-09-17 01:57:32

标签: c++ networking sockets

编辑:重述问题,如果我正在侦听端口54321并且侦听端口12345的本地进程连接到我,创建套接字s,我如何实际找到它正在侦听的端口?

sockaddr_in addr;
int len = sizeof(addr);
getpeername(s, (sockaddr*)&addr, &len);
cout << string(inet_ntoa(addr.sin_addr)) << ":" << ntohs(addr.sin_port) << endl;

输出不应该是127.0.0.1:12345吗?相反,我得到127.0.0.1:62305或其他一些任意端口号。这是我的错误,还是应该这样?

4 个答案:

答案 0 :(得分:1)

要详细说明RageZ的答案,getpeername()将返回套接字另一端的端口和地址。端口12345是您传递给bind()的目标的地址。通常,客户端(例如telnet,nc等等)不会在其套接字上调用bind(),因为它们不想监听连接。因此操作系统会为它们分配一个任意的“短暂”端口号。

通常,在了解TCP连接的源端口方面几乎没有用处。

答案 1 :(得分:1)

看起来你有两个进程正在侦听两个端口 - 这两个侦听套接字是相互独立的。然后在其中一个进程中创建第三个客户端套接字并连接到另一个进程。第三个套接字通过TCP堆栈(在您的情况下为62305)分配给它ephemeral port。因此,连接由元组{source ip,source port,target ip,target port} - {127.0.0.1,62305,127.0.0.1,54321}表示。此连接与连接过程可能具有的任何侦听套接字完全无关。如果您需要了解它们,则必须明确设计应用程序以在对等端之间传递端口号。如果您只是想知道什么进程有什么套接字,那么总是lsof

答案 2 :(得分:0)

getpeername提供有关客户端而非服务器的详细信息,因此您可以获得一些随机端口。

您可以看到man页面

干杯

答案 3 :(得分:0)

如果已连接,您应该127.0.0.1:12345。你确定它已经连接好了吗?

您需要检查getpeername()的返回代码,以确保没有错误。