getsockname与getpeername
2014-04-02 21:04
411 查看
getsockname与getpeername是返回套接口关联的本地协议地址和远程协议地址。
int getsockname(int sockfd, struct sockaddr * localaddr, socken_t * addrlen);
int getpeername(int sockfd, struct sockaddr * peeraddr, socken_t * addrlen);
返回0表示成功,返回1表示出错
参数sockfd表示你要获取的套接口的描述字。
localaddr返回本地协议地址描述结构, peeraddr返回远程协议地址描述结构,addrlen分别是上述2个结构的长度。
下面是使用样例
client.c
补充:getsockname和getpeername调度时机很重要,如果调用时机不对,则无法正确获得地址和端口。
TCP
对于服务器来说,在bind以后就可以调用getsockname来获取本地地址和端口,虽然这没有什么太多的意义。getpeername只有在链接建立以后才调用,否则不能正确获得对方地址和端口,所以他的参数描述字一般是链接描述字而非监听套接口描述字。
对于客户端来说,在调用socket时候内核还不会分配IP和端口,此时调用getsockname不会获得正确的端口和地址(当然链接没建立更不可能调用getpeername),当然如果调用了bind 以后可以使用getsockname。想要正确的到对方地址(一般客户端不需要这个功能),则必须在链接建立以后,同样链接建立以后,此时客户端地址和端口就已经被指定,此时是调用getsockname的时机。
UDP
UDP分为链接和没有链接2种(这个到UDP与connect可以找到相关内容)
没有链接的UDP不能调用getpeername,但是可以调用getsockname,和TCP一样,他的地址和端口不是在调用socket就指定了,而是在第一次调用sendto函数以后
已经链接的UDP,在调用connect以后,这2个函数都是可以用的(同样,getpeername也没太大意义。如果你不知道对方的地址和端口,不可能会调用connect)。
int getsockname(int sockfd, struct sockaddr * localaddr, socken_t * addrlen);
int getpeername(int sockfd, struct sockaddr * peeraddr, socken_t * addrlen);
返回0表示成功,返回1表示出错
参数sockfd表示你要获取的套接口的描述字。
localaddr返回本地协议地址描述结构, peeraddr返回远程协议地址描述结构,addrlen分别是上述2个结构的长度。
下面是使用样例
#include "/programe/net/head.h" #include "stdio.h" #include "stdlib.h" int main(int argc, char ** argu) { int listenfd; struct sockaddr_in servaddr; pid_t pid; char temp[100]; int n = 0; listenfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(atoi(argu[1])); bind(listenfd, (struct socket_addr *)&servaddr, sizeof(servaddr)); listen(listenfd, n); for(;;) { struct sockaddr_in local; int connfd = accept(listenfd, (struct sockaddr *)NULL, NULL); if((pid = fork()) == 0) { struct sockaddr_in serv, guest; char serv_ip[20]; char guest_ip[20]; int serv_len = sizeof(serv); int guest_len = sizeof(guest); getsockname(connfd, (struct sockaddr *)&serv, &serv_len); getpeername(connfd, (struct sockaddr *)&guest, &guest_len); inet_ntop(AF_INET, &serv.sin_addr, serv_ip, sizeof(serv_ip)); inet_ntop(AF_INET, &guest.sin_addr, guest_ip, sizeof(guest_ip)); printf("host %s:%d guest %s:%d\n", serv_ip, ntohs(serv.sin_port), guest_ip, ntohs(guest.sin_port)); char buf[] = "hello world"; write(connfd, buf, strlen(buf)); close(connfd); exit(0); } close(connfd); } }
client.c
#include "/programe/net/head.h" #include "stdio.h" #include "stdlib.h" int main(int argc, char ** argv) { int sockfd, n; int my; char buf[100]; struct sockaddr_in servaddr; if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("create socket error\n"); exit(1); } bzero(&servaddr, sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(atoi(argv[2])); if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) < 0) { printf("inet_pton error\n"); exit(1); } if((my = connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr))) < 0) { printf("connect error\n"); exit(1); } struct sockaddr_in serv, guest; int serv_len = sizeof(serv); int guest_len = sizeof(guest); char serv_ip[20], guest_ip[20]; getsockname(sockfd, (struct sockaddr *)&guest, &guest_len); getpeername(sockfd, (struct sockaddr *)&serv, &serv_len); inet_ntop(AF_INET, &guest.sin_addr, guest_ip, sizeof(guest_ip)); inet_ntop(AF_INET, &serv.sin_addr, serv_ip, sizeof(serv_ip)); printf("host %s:%d, guest %s:%d\n", serv_ip, ntohs(serv.sin_port), guest_ip, ntohs(guest.sin_port)); n = read(sockfd, buf, 100); buf = '\0'; printf("%s\n", buf); getchar(); close(sockfd); exit(0); }
补充:getsockname和getpeername调度时机很重要,如果调用时机不对,则无法正确获得地址和端口。
TCP
对于服务器来说,在bind以后就可以调用getsockname来获取本地地址和端口,虽然这没有什么太多的意义。getpeername只有在链接建立以后才调用,否则不能正确获得对方地址和端口,所以他的参数描述字一般是链接描述字而非监听套接口描述字。
对于客户端来说,在调用socket时候内核还不会分配IP和端口,此时调用getsockname不会获得正确的端口和地址(当然链接没建立更不可能调用getpeername),当然如果调用了bind 以后可以使用getsockname。想要正确的到对方地址(一般客户端不需要这个功能),则必须在链接建立以后,同样链接建立以后,此时客户端地址和端口就已经被指定,此时是调用getsockname的时机。
UDP
UDP分为链接和没有链接2种(这个到UDP与connect可以找到相关内容)
没有链接的UDP不能调用getpeername,但是可以调用getsockname,和TCP一样,他的地址和端口不是在调用socket就指定了,而是在第一次调用sendto函数以后
已经链接的UDP,在调用connect以后,这2个函数都是可以用的(同样,getpeername也没太大意义。如果你不知道对方的地址和端口,不可能会调用connect)。
相关文章推荐
- Socket不能选择本地IP连接问题如何解决
- linux网络编程用到的网络函数详解用和使用示例
- 解决time_wait强制关闭socket
- 深入php socket的讲解与实例分析
- filezilla Failed to create listen socket on port 21 for IPv4 解决办法
- php socket方式提交的post详解
- PHP异步调用socket实现代码
- PHP实现Socket服务器的代码
- udp socket客户端和udp服务端程序示例分享
- 谈谈新手如何学习PHP网络编程第1/2页
- python实现socket端口重定向示例
- Python 网络编程起步(Socket发送消息)
- python实现socket客户端和服务端简单示例
- c# socket网络编程接收发送数据示例代码
- 解析:通过php socket并借助telnet实现简单的聊天程序
- 基于PHP Socket配置以及实例的详细介绍
- 基于TCP异步Socket模型的介绍
- .net的socket异步通讯示例分享
- 浅析PHP Socket技术