zoukankan      html  css  js  c++  java
  • getpeername、getsockname

    函数原型:

    #include<sys/socket.h> 
    int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen); 
    int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);

    函数功能:

    getsockname函数用于获取与某个套接字关联的本地协议地址
    getpeername函数用于获取与某个套接字关联的外地协议地址

    返回值:

    对于这两个函数,如果函数调用成功,则返回0,如果调用出错,则返回-1。

    实例:

    /***
    client.c
    ***/
    #include<stdio.h>
    #include<sys/socket.h>
    #include<netinet/in.h>
    #include<unistd.h>
    #include<string.h>
    #include<arpa/inet.h>
    
    #define PORT 6563
    
    int main(int argc, char **argv)
    {
        struct sockaddr_in servaddr;
        struct sockaddr_in clientaddr;
        int sockfd;
        int clientaddrlen = sizeof(clientaddr);
        char ipAddress[INET_ADDRSTRLEN];
    
        if (argc < 2)
        {
            printf("parameter error");
        }
    
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        memset(&servaddr, 0 ,sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(PORT);
    
        if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
        {
            printf("server address error
    ");
        }
    
        connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    
        getsockname(sockfd, (struct sockaddr*)&clientaddr, &clientaddrlen);
        printf("client:clinet address = %s:%d
    ",inet_ntop(AF_INET,
                    &clientaddr.sin_addr, ipAddress, sizeof(ipAddress)),
                ntohs(clientaddr.sin_port));
        return 0;
    }
    /***
    server.c
    ***/
    #include<sys/socket.h>
    #include<stdio.h>
    #include<netinet/in.h>
    #include<unistd.h>
    #include<string.h>
    #include<arpa/inet.h>
    
    #define MAXLINE 4096
    #define PORT 6563
    #define LISTENQ 1024
    
    int main()
    {
        int listenfd, connfd;
        struct sockaddr_in servaddr;
        struct sockaddr_in listenAddr, connecteAddr, peerAddr;
        int listenAddrlen, connectedAddrlen, perrLen;
    
        char ipAddr[INET_ADDRSTRLEN];
        listenfd = socket(AF_INET, SOCK_STREAM, 0);
        memset(&servaddr, 0 ,sizeof(servaddr));
    
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(PORT);
    
        bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    
        listen(listenfd, LISTENQ);
        listenAddrlen = sizeof(listenAddr);
        getsockname(listenfd,(struct sockaddr *)&listenAddr, 
                &listenAddrlen);
        printf("listen address = %s:%d
    ",inet_ntoa(listenAddr.sin_addr),
                ntohs(listenAddr.sin_port));
    
        while(1)
        {
            connfd = accept(listenfd, (struct sockaddr*)NULL, NULL);
            connectedAddrlen = sizeof(connecteAddr);
            getsockname(connfd, (struct sockaddr*)&connecteAddr, &connectedAddrlen);
            printf("connected server address = %s:%d
    ",inet_ntoa(connecteAddr.sin_addr),
                    ntohs(connecteAddr.sin_port));
    
            getpeername(connfd, (struct sockaddr*)&peerAddr, &perrLen);
            printf("connected peer address = %s:%d
    ",inet_ntop(AF_INET,
                    &peerAddr.sin_addr, ipAddr, sizeof(ipAddr)),
                    ntohs(peerAddr.sin_port));
        }
    
        return 0;
    }    

    运行结果:

    从上面的代码中可以看到,服务器端listenfd套接字描述符对应的地址即为绑定的通配IP地址和指定的端口,而connfd套接字描述符对应的连接的服务器端的地址为内核赋予的地址和用户指定的端口。

    上面的客户端与服务器端的代码中使用了函数inet_ntoa,inet_pton对32位的地址进行转换,其中inet_ntoa是较老的函数,与它一起的还有函数inet_addr和inet_ntoa,这三个函数的定义如下:

    #include<arpa/inet.h> 
    int inet_aton(const char *strptr, struct in_addr *addrptr); 
    in_addr_t inet_addr(const char *strptr); 
    char *inet_ntoa(struct in_addr inaddr);

    inet_aton与inet_addr函数的功能类似,都是将点分十进制的字符串表示的IP地址转换成32位的网络字节序的IPv4地址。

    inet_ntoa函数将32位的网络字节序的IPv4地址转换成点分十进制的字符串表示的IP地址,inet_addr函数已被废弃,并且这三个函数只针对IPv4地址有效,在点分十进制数串和32位的网络字节序二进制值间进行转换,如果要对于IPv4和IPv6都适用,那么使用下面两个函数:

    #include<arpa/inet.h> 
    int inet_pton(int family, const char *strptr, void *addrptr); 
    const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);

    函数中的p和n分别代表表达式(presentation)和数值(numeric)

    所以inet_pton函数将strptr指针所指的字符串转换为网络地址(IPv4和IPv6),再将地址保存到addrptr指向的结构体中,inet_ntop将网络地址转为字符串表示的地址,结果存放在strptr中,len参数是strptr的大小。

    这两个函数支持IPv4和IPv6,所以需要通过参数family来指定,当前要转换的是IPv4地址还是IPv6地址。

  • 相关阅读:
    弹性盒模型
    CSS3属性
    CSS3选择器
    闭包
    angularjs-select2的使用
    angular 分页插件的使用
    webstorm 破解
    数组和字符串之间的转化
    git 拉取分支代码 合分支
    时间戳转化为时间格式 时间格式转为时间戳
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/11844284.html
Copyright © 2011-2022 走看看