协议地址获取函数 -- getsockname、getpeername

2014-07-01 20:58:11   最后更新: 2014-07-01 20:58:11   访问数量:1453




getsockname 和 getpeername 两个函数一个返回与某个套接字关联的本地协议地址,一个返回与某个套接字关联的外地协议地址

int getsockname (int sockfd, struct sockaddr *localaddr, socklen_t *addrlen); int getpeername (int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);

 

定义于 <sys/socket.h> 头文件中,如果调用成功返回0,否则返回-1

 

这两个函数的最后一个参数 addrlen 是一个“值--结果”参数,也就说在函数执行后会将结果填充到该参数中作为返回值之一返回给调用者

 

这两个函数用于下列情况:

在一个没有调用 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); }

 

在这个函数中,由于我们 要分配的子地址结构的类型,所以我们采用 sockaddr_storage 这个通用结构,因为他能够承载系统支持的任何套接字地址结构

  • 在一个以通配IP地址调用 bind 的TCP服务器上,与某个客户的连接诶一旦建立(accept 成功返回),getsockname 就可以用于返回由内核赋予该连接的本地IP地址,在这样的调用中,套接字描述符参数必须是已连接套接字的描述符,而不是监听套接字的描述符
  • 当一个服务器是由调用过 accept 的某个进程通过调用 exec 执行程序时,获取客户身份的唯一途径就是调用 getpeername,inetd(interne超级服务器)fork并exec某个TCP服务器程序时就是这样的情形,如下图所示,inetd 调用 accept 返回两个值:已连接套接字描述符 connfd(函数返回值)与客户的IP地址以及端口号,inetd 随后调用 fork 派生出 inetd 的一个子进程,既然子进程起始于父进程的内存映像的一个副本,附近城中的那个套接字地址结构在子进程中也可用,那个已连接套接字描述符也是如此(描述符在父子进程中是共享的),然而当子进程调用 exec 执行真正的服务器程序时,子进程的内存映像被替换成新的服务器程序文件,因此包含对端地址的那个套接字地址结构就此丢失,不过已连接套接字描述符跨 exec 继续保持开放,所以服务器首先需要调用 getpeername 获取客户的 IP 地址和端口号

 

 






读书笔记      技术帖      c语言      unp      unix网络编程      龙潭书斋      getsockname      getpeername     


京ICP备15018585号