Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C套接字编程:获取服务器绑定到的IP地址(IPv6或IPv4)以及连接到的客户端?_C_Sockets_Networking - Fatal编程技术网

C套接字编程:获取服务器绑定到的IP地址(IPv6或IPv4)以及连接到的客户端?

C套接字编程:获取服务器绑定到的IP地址(IPv6或IPv4)以及连接到的客户端?,c,sockets,networking,C,Sockets,Networking,我已经编写了如下代码。此代码应能够检索被动_套接字(服务器绑定其套接字的位置)和连接_套接字(客户端已连接到的位置)的IP地址 result\t print\u socket\u address(int sockfd,socket\u type\u socket\u type){ char*ip_address;//绑定到的地址(被动)套接字 int-port;//端口(被动)套接字已绑定到 开关(插座式) { 外壳无源插座: if(获取当前地址和端口(sockfd和ip地址和端口)=失败){

我已经编写了如下代码。此代码应能够检索被动_套接字(服务器绑定其套接字的位置)和连接_套接字(客户端已连接到的位置)的IP地址

result\t print\u socket\u address(int sockfd,socket\u type\u socket\u type){
char*ip_address;//绑定到的地址(被动)套接字
int-port;//端口(被动)套接字已绑定到
开关(插座式)
{
外壳无源插座:
if(获取当前地址和端口(sockfd和ip地址和端口)=失败){
fprintf(标准“获取当前地址和端口:失败!\n”);
免费(ip地址);
返回失败;
}
printf(“创建的被动套接字%d绑定到%s:%d\n”,sockfd,ip\U地址,端口);
打破
外壳连接插座:
if(获取对等地址和端口(sockfd、&ip地址和端口)=失败){
fprintf(标准“获取对等地址和端口:失败!\n”);
免费(ip地址);
返回失败;
}
printf(“连接到%s的套接字%d:%d\n”,sockfd,ip\U地址,端口);
打破
违约:
fprintf(标准“不正确的插座类型!\n”);
免费(ip地址);
返回失败;
}
免费(ip地址);
回归成功;
}
/**
*函数检索当前ip地址和端口
*套接字已绑定到给定套接字文件描述符的
*/
结果获取当前地址和端口(int sockfd,字符**ip地址,int*端口){
结构sockaddr sockaddr;
socklen_t sockaddrlen=sizeof(sockaddr);
if(getsockname(sockfd,&sockaddr,&sockaddrlen)<0){
fprintf(stderr,“getsockname:%s\n”,strerror(errno));
返回失败;
}
sockaddr.sa_family=AF_INET6;
从\u sockaddr返回get\u address\u和\u port\u(&sockaddr,ip\u address,port);
}
/**
*函数检索对等ip地址和端口
*对于给定的套接字文件描述符,套接字已连接到
*/
结果\u t获取\u对等\u地址\u和\u端口(int sockfd,char**ip\u地址,int*端口){
结构sockaddr sockaddr;
socklen_t sockaddrlen=sizeof(sockaddr);
if(getpeername(sockfd、sockaddr和sockaddrlen)<0){
fprintf(stderr,“getpeername:%s\n”,strerror(errno));
返回失败;
}
从\u sockaddr返回get\u address\u和\u port\u(&sockaddr,ip\u address,port);
}
/**
*函数从addrinfo结构中展开ip地址和端口
*/
结果\u t从\u addrinfo(const struct addrinfo*addrinfo,char**ip\u地址,int*port)获取\u地址\u和\u端口\u{
从\u sockaddr((struct sockaddr*)addrinfo->ai\u addr,ip\u地址,端口)返回get\u addr\u和\u port\u;
}
/**
*函数从sockaddr结构中展开ip地址和端口
*/
结果\u t从\u sockaddr(const struct sockaddr*sockaddr,char**ip\u地址,int*port)获取\u地址\u和\u端口\u{
*ip地址=(字符*)malloc(INET6地址*大小(字符));
//将网络地址转换为演示文稿地址
如果(inet_ntop(sockaddr->sa_family,get_in_addr(sockaddr),*ip_地址,INET6_ADDRSTRLEN*sizeof(char))==NULL){
fprintf(标准,“inet\u ntop:%s\n”,strerror(errno));
返回失败;
}
//将网络端口转换为主机端口
*port=ntohs(在端口中获取端口(sockaddr));
回归成功;
}
/**
*函数在\u addr或in6\u addr结构中从展开
*sockaddr结构取决于地址族
*AF_INET或AF_INET6
*/
void*get\u in\u addr(const struct sockaddr*sa){
if(sa->sa_family==AF_INET)//IPv4地址
return&(((struct sockaddr_in*)sa)->sin_addr);
//else IPv6地址
返回((结构sockaddr_in6*)sa)->sin6_addr);
}
/**
*从sockaddr结构在_端口中展开函数
*取决于地址系列AF_INET或AF_INET6
*/
in_port\u t get_in_port(const struct sockaddr*sa)
{
if(sa->sa_family==AF_INET)//IPv4地址
返回(((结构sockaddr_in*)sa)->sin_端口;
//else IPv6地址
返回((结构sockaddr_in6*)sa)->sin6_端口;
}
但是当我使用这个代码时,我会有一些奇怪的行为。返回我的服务器边界套接字所在的IP地址,例如:

已创建绑定到::ba54:431c:f9:55401的被动套接字4

55401是端口号,它是正确的。但这是什么::ba54:431c:f9?我想这可能是IPv6。但是为什么呢?我的局域网计算机的IP地址是192.168.8.102! 更多信息当我尝试通过客户端程序连接此服务器时,我必须使用192.168.8.102 IP地址才能连接,否则使用此::ba54:431c:f9我会收到类似“未找到路由”的错误?当客户端使用192.168.8.102 IP地址与服务器连接,然后打印其连接到的计算机的IP地址和端口号时,我会得到另一个奇数IP地址,如下所示:

插座3连接到::3300:5208:6d16:9c88:55401

所以这里只有端口号匹配,IP地址不正确! 在与服务器连接之前本地绑定时,通过客户端套接字进行的更多绑定的IP地址与所连接计算机的IP地址相同(它在我的LAN网络中是物理上不同的计算机),即:3300:5208:6d16:9c88:52040,其中52040是客户端绑定其套接字的端口

我甚至尝试将服务器计算机192.168.8.1的IP地址转换为IPv6,但我得到的结果是:0:0:0:0:0:ffff:c0a8:866,当在客户端程序中用于连接到服务器时,该地址可以正常工作!但是,使用上述函数的客户端会打印出完全不同的IP地址,如:3300:5208:6d16:9c88:52040

那么,我应该如何将此函数写入:

  • 启用服务器打印IP地址及其绑定的端口号(通常IPv6或IPv4可以连接到它选择的任何地址/端口)

  • 使客户端能够打印其绑定到并连接到的IP地址和端口号(通常可以使用IPv4或IPv6,具体取决于t
    result_t print_socket_address(int sockfd, socket_type_t socket_type) {
    
        char *ip_address; // address (passive) socket was binded to
        int port; // port (passive) socket was binded to
    
        switch(socket_type)
        {
            case PASSIVE_SOCKET:
                if(get_current_address_and_port(sockfd, &ip_address, &port) == FAILURE) {
                    fprintf(stderr, "get_current_address_and_port: faild!\n");
                    free(ip_address);
                    return FAILURE;
                }
                printf("Created passive socket %d binded to %s:%d\n", sockfd, ip_address, port);
                break;
            case CONNECTION_SOCKET:
                if(get_peer_address_and_port(sockfd, &ip_address, &port) == FAILURE) {
                    fprintf(stderr, "get_peer_address_and_port: faild!\n");
                    free(ip_address);
                    return FAILURE;
                }
                printf("Socket %d connected to %s:%d\n", sockfd, ip_address, port);
                break;
            default:
                fprintf(stderr, "Incorrect socket type!\n");
                free(ip_address);
                return FAILURE;
        }
    
        free(ip_address);
        return SUCCESS;
    }
    
    /**
     * function retrieves current ip address and port
     * socket is bound to for given socket file descriptor
     */
    result_t get_current_address_and_port(int sockfd, char **ip_address, int *port) {
    
        struct sockaddr sockaddr;
        socklen_t sockaddrlen = sizeof(sockaddr);
    
        if(getsockname(sockfd, &sockaddr, &sockaddrlen) < 0) {
            fprintf(stderr, "getsockname: %s\n", strerror(errno));
            return FAILURE;
        }
    
        sockaddr.sa_family = AF_INET6;
    
        return get_address_and_port_from_sockaddr(&sockaddr, ip_address, port);
    }
    
    /**
     * function retrieves peer ip address and port
     * socket is connected to for given socket file descriptor
     */
    result_t get_peer_address_and_port(int sockfd, char **ip_address, int *port) {
    
        struct sockaddr sockaddr;
        socklen_t sockaddrlen = sizeof(sockaddr);
    
        if(getpeername(sockfd, &sockaddr, &sockaddrlen) < 0) {
            fprintf(stderr, "getpeername: %s\n", strerror(errno));
            return FAILURE;
        }
    
        return get_address_and_port_from_sockaddr(&sockaddr, ip_address, port);
    }
    
    /**
     * function unwrap ip address and port from addrinfo structure
     */
    result_t get_address_and_port_from_addrinfo(const struct addrinfo *addrinfo, char **ip_address, int *port) {
    
        return get_address_and_port_from_sockaddr((struct sockaddr *)addrinfo->ai_addr, ip_address, port);
    }
    
    /**
     * function unwrap ip address and port from sockaddr structure
     */
    result_t get_address_and_port_from_sockaddr(const struct sockaddr *sockaddr, char **ip_address, int *port) {
    
        *ip_address = (char *) malloc(INET6_ADDRSTRLEN * sizeof(char));
    
        // converting network address to presentation address
        if(inet_ntop(sockaddr->sa_family, get_in_addr(sockaddr), *ip_address, INET6_ADDRSTRLEN * sizeof(char)) == NULL) {
            fprintf(stderr, "inet_ntop: %s\n", strerror(errno));
            return FAILURE;
        }
    
        // converting network port to host port
        *port = ntohs(get_in_port(sockaddr));
    
        return SUCCESS;
    }
    
    /**
     * function unwrap in_addr or in6_addr structure from
     * sockaddr structure depending on address family
     * AF_INET or AF_INET6
     */
    void *get_in_addr(const struct sockaddr *sa) {
    
        if( sa->sa_family == AF_INET) // IPv4 address
            return &(((struct sockaddr_in*)sa)->sin_addr);
        // else IPv6 address
        return &(((struct sockaddr_in6*)sa)->sin6_addr);
    }
    
    /**
     * function unwrap in_port from sockaddr structure
     * depending on address family AF_INET or AF_INET6
     */
    in_port_t get_in_port(const struct sockaddr *sa)
    {
        if( sa->sa_family == AF_INET ) // IPv4 address
            return (((struct sockaddr_in*)sa)->sin_port);
        // else IPv6 address
        return (((struct sockaddr_in6*)sa)->sin6_port);
    }
    
        sockaddr.sa_family = AF_INET6;
    
    result_t get_current_address_and_port(int sockfd, char **ip_address, int *port) {
    
        struct sockaddr_storage address = {0};
        socklen_t sockaddrlen = sizeof(address);
    
        if(getsockname(sockfd, (struct sockaddr*)(&address), &sockaddrlen) < 0) {
            fprintf(stderr, "getsockname: %s\n", strerror(errno));
            return FAILURE;
        }
    
        return get_address_and_port_from_sockaddr((struct sockaddr*)(&address), ip_address, port);
    }
    
    
    result_t get_peer_address_and_port(int sockfd, char **ip_address, int *port) {
        struct sockaddr_storage address = {0};
        socklen_t sockaddrlen = sizeof(address);
    
        if(getpeername(sockfd, (struct sockaddr*)(&address), &sockaddrlen) < 0) {
            fprintf(stderr, "getpeername: %s\n", strerror(errno));
            return FAILURE;
        }
    
        return get_address_and_port_from_sockaddr((struct sockaddr*)(&address), ip_address, port);
    }