【问题标题】:How to get ip address from sock structure in c?如何从c中的sock结构中获取IP地址?
【发布时间】:2011-03-04 21:47:33
【问题描述】:

我正在编写简单的服务器/客户端并尝试获取客户端 IP 地址并将其保存在服务器端以决定哪个客户端应该进入关键部分。我用谷歌搜索了几次,但找不到从 sock 结构中获取 IP 地址的正确方法。

我相信这是一种在服务器接受来自客户端的请求后从 sock 结构中获取 IP 的方法。更具体地说,在服务器执行后的 c 中

csock = accept(ssock, (struct sockaddr *)&client_addr, &clen) 

谢谢

【问题讨论】:

    标签: c sockets ip-address


    【解决方案1】:

    好的,假设您使用的是 IPV4,然后执行以下操作:

    struct sockaddr_in* pV4Addr = (struct sockaddr_in*)&client_addr;
    struct in_addr ipAddr = pV4Addr->sin_addr;
    

    如果您希望将 IP 地址作为字符串,请执行以下操作:

    char str[INET_ADDRSTRLEN];
    inet_ntop( AF_INET, &ipAddr, str, INET_ADDRSTRLEN );
    

    IPV6 也很简单...

    struct sockaddr_in6* pV6Addr = (struct sockaddr_in6*)&client_addr;
    struct in6_addr ipAddr       = pV6Addr->sin6_addr;
    

    获取字符串与 IPV4 几乎相同

    char str[INET6_ADDRSTRLEN];
    inet_ntop( AF_INET6, &ipAddr, str, INET6_ADDRSTRLEN );
    

    【讨论】:

    • 您忘记将str 缓冲区传递给inet_ntop()。而sin_addr 是一个结构——必须使用sin_addr.s_addr。值得注意的是,IPv4 地址以网络字节顺序存储,要将其视为十六进制数字,需要使用 ntohl(pV4Addr->sin_addr.s_addr)
    • 点数......你也错过了我不使用小写字母“in6_addr”;)在 ntohl 前面,我不经常打扰,因为我仍然可以进行相等检查(前提是两者都按网络顺序) 并且它会破坏 inet_ntop(不是吗?)。
    • 这个问题被标记为 C - 你不能在 struct sockaddr_in * 这样的类型中省略 struct。此外,IPV4 方法应使用struct in_addr 而不是int 来存储地址,类似于您显示的 IPV6 方法。
    【解决方案2】:

    提取 IP 地址和端口号的更简单和正确的方法是:

    printf("IP address is: %s\n", inet_ntoa(client_addr.sin_addr));
    printf("port is: %d\n", (int) ntohs(client_addr.sin_port));
    

    SoapBox 接受的答案并不适用于所有架构。见Big and Little Endian

    【讨论】:

      【解决方案3】:

      假设client_addrstruct sockaddr_in(通常是这样)。您可以从client_addr.sin_addr.s_addr 获取 IP 地址(作为 32 位无符号整数)。

      您可以通过这种方式将其转换为字符串:

      printf("%d.%d.%d.%d\n",
        int(client.sin_addr.s_addr&0xFF),
        int((client.sin_addr.s_addr&0xFF00)>>8),
        int((client.sin_addr.s_addr&0xFF0000)>>16),
        int((client.sin_addr.s_addr&0xFF000000)>>24));
      

      【讨论】:

      • 您应该使用 inet_ntoa() 而不是手动摆弄位。
      • inet_ntoa 不是线程安全的,尽管在大多数使用它的情况下这可能并不重要。一个安全的替代方案是inet_ntop
      • @RemyLebeau 又好又简单。我喜欢它。
      猜你喜欢
      • 1970-01-01
      • 2020-09-16
      • 1970-01-01
      • 1970-01-01
      • 2011-04-04
      • 2013-02-27
      • 2011-10-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多