zoukankan      html  css  js  c++  java
  • 通过网络socket获取对方 ip 和port

    int getpeername(int s, struct sockaddr *name, socklen_t *namelen);
    描述
    获取socket的对方地址
    struct sockaddr_in sa;
    int len = sizeof(sa);
    if(!getpeername(sockfd, (struct sockaddr *)&sa, &len))
    {
    printf( "对方IP:%s ", inet_ntoa(sa.sin_addr));
    printf( "对方PORT:%d ", ntohs(sa.sin_port));
    }
    补充:getsockname和getpeername调度时机很重要,如果调用时机不对,则无法正确获得地址和端口。
    TCP
    对于服务器来说,在bind以后就可以调用getsockname来获取本地地址和端口,虽然这没有什么太多的意义。getpeername只有在链接建立以后才调用,否则不能正确获得对方地址和端口,所以他的参数描述字一般是链接描述字而非监听套接口描述字。
    对于客户端来说,在调用socket时候内核还不会分配IP和端口,此时调用getsockname不会获得正确的端口和地址(当然链接没建立更不可能调用getpeername),当然如果调用了bind 以后可以使用getsockname。想要正确的到对方地址(一般客户端不需要这个功能),则必须在链接建立以后,同样链接建立以后,此时客户端地址和端口就已经被指定,此时是调用getpeername的时机。
    UDP
    UDP分为链接和没有链接2种(这个到UDP与connect可以找到相关内容)
    没有链接的UDP不能调用getpeername,但是可以调用getsockname,和TCP一样,他的地址和端口不是在调用socket就指定了,而是在第一次调用sendto函数以后
    已经链接的UDP,在调用connect以后,这2个函数都是可以用的(同样,getpeername也没太大意义。如果你不知道对方的地址和端口,不可能会调用connect)。

        //获取fd对应的ip和port
        static void get_peer_ip_port(int fd, char **ip, int *port)
        {
            int client_fd = fd;
            
            // discovery client information
            struct sockaddr_in addr;
            socklen_t addrlen = sizeof(addr);
            if(getpeername(client_fd, (struct sockaddr*)&addr, &addrlen) == -1){
                fprintf(stderr,"discovery client information failed, fd=%d, errno=%d(%#x). ", client_fd, errno, errno);        
                return;
            }
         
            // ip v4 or v6
            char *buf = malloc(INET6_ADDRSTRLEN);
            memset(buf, 0, INET6_ADDRSTRLEN);
            
            if((inet_ntop(addr.sin_family, &addr.sin_addr, buf, INET6_ADDRSTRLEN)) == NULL){
            fprintf(stderr,"convert client information failed, fd=%d, errno=%d(%#x). ", client_fd, errno, errno);        
                return;
            }
            *port = ntohs(addr.sin_port);
            fprintf(stdout, "get peer ip of client ip=%s, port=%d, fd=%d ", buf, *port, client_fd);
            *ip = buf;
            
            return;
        }

  • 相关阅读:
    day15-collection和其子类
    day14-正则表达式和常用类
    day13-StringBuffer和数组高级,Arrays
    day12-Scanner和String
    day11-object
    linux进程(一)
    CentOS6与CentOS7的启动过程
    linux特殊权限(acl)
    linux系统权限(基本权限)
    linux系统用户管理(二)
  • 原文地址:https://www.cnblogs.com/YZFHKMS-X/p/11761589.html
Copyright © 2011-2022 走看看