-
这两个函数与域名(第9章)没有任何联系
#include<sys/socket.h>
int getsockname(int sockfd,struct sockaddr *localaddr,socklen_t *addrlen);
int getperrname(int sockfd,struct sockaddr *perraddr,socklen_t *addrlen);
- getsockname:用于获取本地协议地址
- getpeername:用于获取外地协议地址
二、getsockname应用场景参数:
- 参数1:套接字描述符
- 参数2:用来保存地址信息的套接字结构体
- 参数3:相对于参数2的结构体地址大小指针
返回值:
- 成功:0
- 失败:-1
- 在一个没有调用bind的TCP客户上,connect成功返回后,getsockname用于返回由内 核赋予该连接的本地IP地址和本地端口号。
- 在以端口号0调用bind(告知内核去选择本地端口号)后,getsockname用于返回由内 核赋予的本地端口号
- getsockname可用于获取某个套接字的地址族,如下面代码所示
int
sockfd_to_family(int sockfd)
{
struct sockaddr_storage ss;
socklen_t len;
len = sizeof(ss);
if (getsockname(sockfd, (SA *) &ss, &len) < 0)
return(-1);
return(ss.ss_family);
}
- 在一个以通配IP地址调用bind的TCP服务器上,与某个客户的连接一旦建立 (accept成功返回),getsockname就可以用于返回由内核赋予该连接的本地IP地址。在这样的调用中,套接字描述符参数必须是已连接套接字的描述符,而不是监听套接字的 描述符
- 当一个服务器是由调用过accept的某个进程通过调用exec执行程序时,它能够获取客 户身份的唯一途径便是调用getpeername。inetd(13.5节)fork并exec某个TCP服务 器程序时就是如此情形,如修所示。inetd调用accept(左上方方框)返回两个值: 已连接套接字描述符connfd,这是函数的返回值;客户的IP地址及端口号,如图中标有 “对端地址”的小方框所示(代表一个网际网套接字地址结构)。inetd随后调用fork, 派生出inetd的一个子进程。既然子进程起始于父进程的内存映像的一个副本,父进程 中的那个套接字地址结构在子进程中也可用,那个已连接套接字描述符也是如此(因为 描述符在父子进程之间是共享的)。然而当子进程调用exec执行真正的服务器程序(譬 如说Telnet服务器程序)时,子进程的内存映像被替换成新的Telnet服务器的程序文件(也 就是说包含对端地址的那个套接字地址结构就此丢失),不过那个已连接套接字描述符 跨exec继续保持开放。Telnet服务器首先调用的函数之一便是getpeername,用于获取 客户的IP地址和端口号
int sockfd=socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_storage ss;
socklen_t len;
len=sizeof(ss);
if(getsockname(sockfd,(struct sockaddr*)&ss,&len)<0)
return -1;
- 既然不知道要分配的套接字地址结构的类型,我们于是采用sockaddr_storage这个通 用结构,因为它能够承载系统支持的任何套接字地址结构