`
memorymyann
  • 浏览: 270801 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

5.getsockname与getpeername

阅读更多

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个结构的长度。这个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);
        }
}

 

 

[root@liumengli net]# cat client1.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[n] = '\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)。

分享到:
评论

相关推荐

    易语言取远程端口信息

    易语言取远程端口信息源码,取远程端口信息,TCP连接,htons,inet_addr,Connect,WSAStartup,WSACleanup,socket,closesocket,getsockname,getpeername,inet_ntoa,ntohs

    UNIX Network Programming Volume 1, Third Edition (Unix网络编程卷1第3版英文版)

    getsockname and getpeername Functions Section 4.11. Summary Exercises Chapter 5. TCP Client/Server Example Section 5.1. Introduction Section 5.2. TCP Echo Server: main Function Section ...

    第3课-Python网络编程基础.ppt

    例如,`socket.getpeername()`返回套接字的远程连接方的地址,`socket.getsockname()`获取套接字自身的地址。`socket.setsockopt()`允许设置套接字的选项,以控制其行为。 此外,Socket库还提供了处理异常和关闭套...

    unix网络编程卷1和卷2源代码

    5. **套接字选项与系统调用**:getsockopt、setsockopt用于设置和查询套接字选项,getsockname、getpeername获取套接字信息。 6. **套接字过滤器与SOCK_RAW**:使用SOCK_RAW套接字直接处理网络层协议,如ICMP和RAW ...

    Python TCP通信客户端服务端代码实例

    print('socket peer:', scc.getpeername()) while True: message = scc.recv(42) if not message: break print('收到16-octet消息:', message.decode('utf-8')) ``` 服务端首先创建一个socket对象,设置套...

    Winsock 函数参考

    11. **getpeername** 和 **getsockname**:这两个函数分别用于获取已连接套接字的远程(对端)和本地地址信息。 12. **closesocket**:用于关闭套接字,释放相关的系统资源。在不再需要使用套接字时,必须调用此...

    windows socket api函数大全

    5. **getpeername()**:获取与Socket连接的对端的地址信息。 6. **getsockname()**:获取Socket自身的地址信息。 7. **getsockopt()**和**setsockopt()**:设置和获取Socket的选项,如超时时间、接收缓冲区大小等。 ...

    2018年C++教程网的linux网络编程视频共41集百度云下载链接.rar

    getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程与SIGCHLD信号 12socket编程(七) TCP 11种状态 连接建立三次握手、连接终止四...

    WinSock函数使用详解与查询手册 chm.rar

    此外,WinSock还包含其他辅助函数,如`gethostbyname()`用于解析主机名到IP地址,`getsockname()`获取套接字的本地地址,`getpeername()`获取连接套接字的远程地址,以及`select()`用于多路复用I/O,可以同时检查多...

    [免费]2018年C++教程网的linux网络编程视频百度云下载链接.rar

    getsockname、getpeername gethostname、gethostbyname、gethostbyaddr 11socket编程(六) TCP回射客户/服务器 TCP是个流协议 僵进程与SIGCHLD信号 12socket编程(七) TCP 11种状态 连接建立三次握手、...

    Windows Sockets网络编程 可能是最清晰版本(Windows Sockets 2规范解释小组负责人亲自执笔。)总共4个包,part1

    《Windows Sockets网络编程》是WindowsSockets网络编程领域公认的经典著作,由Windows ...C.5 按数值排序的错误代码表 附录D 用户必备 D.1 重要文件 D.2 编译与链接机制 D.3 各种WinSock的使用 D.4 各种编程语言的使用

    Windows Sockets网络编程 总计4个包,part2

    《Windows Sockets网络编程》是WindowsSockets网络编程领域公认的经典著作,由Windows ...C.5 按数值排序的错误代码表 附录D 用户必备 D.1 重要文件 D.2 编译与链接机制 D.3 各种WinSock的使用 D.4 各种编程语言的使用

    TCPIP详解卷[1].part06

    26.4.5 半双工、一次一字符、一次 一行或行方式 304 26.4.6 同步信号 306 26.4.7 客户的转义符 306 26.5 Telnet举例 306 26.5.1 单字符方式 306 26.5.2 行方式 310 26.5.3 一次一行方式(准行方式) 312 26.5.4 行方式...

    WS2_32.Lib

    WS2_32.Lib还包含了一些用于错误处理和状态查询的函数,例如`getsockopt()`、`setsockopt()`用于获取或设置套接字选项,`gethostbyname()`和`gethostbyaddr()`用于解析主机名或地址,`getpeername()`和`getsockname...

    VC获取远端iP信息

    - **`getpeername()`** 函数用于获取与套接字连接的远端节点的地址信息。 - **`getsockname()`** 函数则用于获取套接字本身的地址信息。 这里我们主要关注的是 `getpeername()` 函数,因为它直接关系到如何获取...

Global site tag (gtag.js) - Google Analytics