通过CSocket获取对端IP地址和端口号的方法

版权申诉
5星 · 超过95%的资源 3 下载量 80 浏览量 更新于2024-09-10 收藏 7KB TXT 举报
该问题主要讨论如何从一个基于CSocket的网络通信中获取对方的IP地址和端口号。在Windows编程中,特别是使用MFC(Microsoft Foundation Classes)库进行网络编程时,CSocket类是用于处理套接字操作的基础类。 在CSocket对象与远程主机建立连接后,可以通过调用特定的函数来获取对方的IP地址和端口号。在给出的信息中,用户们提到了`getpeername`函数,这是在Winsock API中用于获取与套接字连接的对端(peer)的网络地址和端口的关键函数。 `getpeername`函数的定义如下: ```cpp int getpeername( SOCKET s, // 套接字句柄 struct sockaddr* name, // 用于存储对端地址的结构体指针 int* namelen // 对端地址结构体的大小指针 ); ``` 参数解释: - `s`:表示已经建立连接的套接字句柄。 - `name`:指向一个`sockaddr`结构体的指针,此结构体将用于存储对端的网络地址信息。 - `namelen`:在调用函数前,它应该包含`name`指向的结构体的大小。在函数返回后,它会被更新为实际返回的地址结构体的大小。 `getpeername`函数通常只能在已连接的套接字上使用,对于面向连接的TCP套接字,它会返回与之连接的远程主机的地址和端口。对于无连接的UDP套接字,如果之前调用了`connect`函数指定了一个目标地址,`getpeername`会返回这个指定的地址;而如果使用了`sendto`函数发送数据到不同的地址,`getpeername`不会返回那些地址。 为了从`sockaddr`结构体中提取出具体的IP地址和端口号,通常需要将其转换为更易读的`sockaddr_in`结构体,因为`sockaddr_in`包含了IPv4地址和端口号: ```cpp struct sockaddr_in { short sin_family; // 地址族,通常为AF_INET u_short sin_port; // 端口号,网络字节序 struct in_addr sin_addr; // IP地址,网络字节序 char sin_zero[8]; // 填充到结构体大小为16字节 }; struct in_addr { u_long s_addr; // IPv4地址,网络字节序 }; ``` 使用`getpeername`获取到的地址信息是网络字节序,所以在显示或比较时需要转换为本地字节序。例如,可以使用`ntohl`和`ntohs`函数进行转换: ```cpp in_addr_t ip = ntohl(sockaddr_in.sin_addr.s_addr); // 转换IP地址 u_short port = ntohs(sockaddr_in.sin_port); // 转换端口号 ``` 最后,需要注意的是,`getpeername`函数可能返回错误代码,因此在调用后应检查返回值,如`WSAGetLastError`函数可获取最近一次Winsock错误代码,以便进行错误处理。 要从CSocket对象获取对方的IP地址和端口号,需要使用`getpeername`函数,并结合`sockaddr`和`sockaddr_in`结构体进行适当的数据转换。