winsock在哪里存储一个socket的IP地址?

7
假设我有一个简单的winsock服务器,它有一个监听套接字,当连接被接受时,把套接字存储在套接字数组中(以允许多个连接)。 如何获取特定连接的IP地址?它是否存储在套接字句柄中?

附注:套接字句柄在某种程度上只是一个整数变量的typedef。在*nix上,程序员使用实际的int来跟踪这些句柄。 - dutt
1
句子“Nothing is "stored in the handle"; it's just a handle, not an object!”的意思是“没有任何数据存储在句柄中;句柄只是一个引用,而不是一个对象!”。这个句柄指向内核对象(显然你不能直接访问),而该对象确实跟踪相关的IP地址。getsockname/getpeername调用内核并检索与传递进来的句柄对应的地址字段(由于Windows很奇怪,无法像其他操作系统那样使用fd和简单的系统调用,因此SOCKET int被WinSock映射到底层HANDLE上)。 - Nicholas Wilson
2个回答

8
只要套接字保持连接,您可以获取自己的套接字地址和对等方的套接字地址。
getsockname将为您提供本地名称(即来自管道的您一侧) getpeername将为您提供对等方名称(即远程管道的另一侧)
此信息仅在套接字打开/连接时可用,因此如果可以在对等方断开连接后使用,则最好将其存储在某个地方。

7

是的,它被存储在 socketaddr_in 结构中,您可以使用以下方法提取它:

SOCKADDR_IN client_info = {0};
int addrsize = sizeof(client_info);

// get it during the accept call
SOCKET client_sock = accept(serv, (struct sockaddr*)&client_info, &addrsize);

// or get it from the socket itself at any time
getpeername(client_sock, &client_info, sizeof(client_info));

char *ip = inet_ntoa(client_info.sin_addr);

printf("%s", ip);

1
一些评论/更正:0 SOCKADDR_IN 真的存在吗? 1 应该是 sockaddr_in 而不是 socketaddr_in。 2 您忘记传递 client_info 的地址(两次); 3 client 没有被声明。 4 accept() 需要一个第三个参数!至少4个不准确 -> -1 - alk
感谢您的更正。我会编辑答案并加入它们。这个答案是从链接的Stack Overflow答案中提取的,我承认我没有100%地检查它。此外,该答案是针对问题的上下文而言的。在这个例子中不需要声明客户端。 - Serdalis
为了让这个例子有意义,我认为 client.sin_addr 应该改为 client_info.sin_addr - alk
好的,最后:accept(serv, &client_info, &addrsize); 会产生两个类型不匹配的警告。第一个是指针类型不匹配,第二个是整数类型不匹配。通常可以通过以下方式解决:socklen_t addrsize = 0; accept(serv, (struct sockaddr *) &client_info, &addrsize); 更新: 如果使用WINSOCK2 API,则后者在Windows上不是问题,因为这里使用了 int* - alk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接