getsockname和getperrname函数
#include <sys/socket.h>
int getsockname(int sockfd,struct sockaddr *localaddr,socklen_t *addrlen);
int getpeername(int sockfd,struct sockaddr *peeraddr,socklen_t *addrlen);
均返回:若成功返回0,出错返回-1;
这两个函数或者返回与套接字关联的本地协议地址(getsockname),或者返回与某个套接字关联的外地协议地址(getpeername)。
这两个函数的最后一个参数都是值-结果参数,这就是说,这两个函数都得装填由localaddr和peeraddr指针所指的套接字地址结构。
需要这两个函数的理由是:
. 在一个没有调用bind的TCP客户上,connect成功返回后,getsockname用于返回有内核赋予该连接的本地IP地址和本地端口号。
. 在一端口号0调用bind(告知内核去选择本地端口号)后,getsockname用于返回内核赋予的端口号。
. getcockname可用于获取某个套接字地址的地址族,如下图所示:

. 在一个以通配字符地址调用bind的TCP服务器上,于某个客户的连接一旦建立(accept成功返回),getsockname就可以用于返回由内核赋予该连接的本地IP地址。在这样的调用中,套接字描述符参数必须是已连接套接字的描述符,而不是监听套接字的描述符。
. 当一个服务器是由调用过accept的某个进程通过调用exec执行程序时,它能够获取客户身份的唯一途径是调用getpeername。inetd fork并exec某个TCP服务程序时就是如此情形,如下图所示。

inetd调用accept返回两个值:已连接套接字描述符conned,这就是函数的返回值;客户的IP地址及端口号,图中标有“对端地址”的小方框所示。inetd随后调用fork,派生出inetd的一个子进程。既然子进程起始于父进程的内存映像的一个副本,父进程中的那个套接字地址结构在子进程中也可用,那个已连接的套接字描水也是如此(因为描述符在父子进程之间是共享的)。然而当子进程调用exec执行真正的服务器程序文件(譬如说Telnet服务程序)时,子进程的内存映像被替换成新的Telnet服务器的程序文件(也就是说包含对端地址的那个套接字地址结构就此丢失),不过那个已连接套接字描述符跨exec继续保持开放。Telnet服务器首先调用的函数之一便是getpeername,用于获取客户的IP地址和端口号。
浙公网安备 33010602011771号