我尝试了以下几种方法:
int sockfd = socket(...);
listen(sockfd, 10);
accept(sockfd, ...);所有调用都没有失败,程序就像我调用bind()一样开始阻塞。在这种情况下会发生什么?由于没有本地地址或端口,接收连接是不可能的吗?或者它隐式地分配了本地地址和端口,现在它正在侦听这些地址和端口?如果是这样,我如何检索这些是什么?
发布于 2009-04-12 00:51:34
调用是有效的,但是因为您没有显式地绑定套接字,所以操作系统或系统库隐式地为您分配了一个端口和默认绑定(与您调用connect(2)而不先调用bind(2)时完全相同)。另外,既然您在前面询问了TCP的内容,那么我假设您在这里谈论的是Internet套接字。
找出操作系统绑定套接字的名称因操作系统而异,因此您必须查找特定的操作系统,但大多数操作系统都提供了netstat或类似的工具,您可以使用它们来查询哪些应用程序正在侦听哪些端口。
正如约翰在评论中提到的,您可以使用getsockname(2)来查找绑定套接字的名称。下面是一个简短的示例:
// ...
// Create socket and set it to listen (we ignore error handling for brevity)
int sock = socket(AF_INET, SOCK_STREAM, 0);
listen(sock, 10);
// Sometime later we want to know what port and IP our socket is listening on
socklen_t addr_size = sizeof(struct sockaddr_in);
struck sockaddr_in addr;
getsockname(sock, (struct sockaddr *)&addr, &addr_size);addr现在将包含套接字正在侦听的IP地址和端口。
发布于 2009-04-12 14:37:12
正如其他人提到的,如果您不绑定()端口,操作系统将分配一个端口。您可以在listen()之后使用getsockname()调用来查看分配了什么地址/端口。然后,如果您将该地址/端口传递给客户端,它就可以连接。
因此,这是有意义的。你可以写一个程序,在那里这是一件有趣的事情。
发布于 2009-04-12 00:50:41
我怀疑你永远不会得到一个连接。您可以检查是否有一个新的套接字侦听,通过在您的操作系统上执行"netstat -an“之前和之后运行程序。
我在C#中也做了同样的事情:
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Listen(1);
socket.Accept();我在第二行得到一个异常,它以一种间接的方式通知我需要绑定。当然,它可以很好地与以下各项配合使用:
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Loopback, 4567));
socket.Listen(1);
socket.Accept();我也测试了Udp套接字,同样的事情,Windows在监听调用上不满意,除非绑定已经完成。由于Winsock套接字调用只是对Winsock的包装,因此这种行为很可能对.Net上的所有Winsock派生库都是相同的。
https://stackoverflow.com/questions/741061
复制相似问题