如何从c中的sock结构获取ip地址?

REA*_*EE 34 c sockets ip-address

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

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

csock = accept(ssock, (struct sockaddr *)&client_addr, &clen) 
Run Code Online (Sandbox Code Playgroud)

谢谢

Goz*_*Goz 47

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

struct sockaddr_in* pV4Addr = (struct sockaddr_in*)&client_addr;
struct in_addr ipAddr = pV4Addr->sin_addr;
Run Code Online (Sandbox Code Playgroud)

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

char str[INET_ADDRSTRLEN];
inet_ntop( AF_INET, &ipAddr, str, INET_ADDRSTRLEN );
Run Code Online (Sandbox Code Playgroud)

IPV6也很简单......

struct sockaddr_in6* pV6Addr = (struct sockaddr_in6*)&client_addr;
struct in6_addr ipAddr       = pV6Addr->sin6_addr;
Run Code Online (Sandbox Code Playgroud)

并获得一个字符串几乎与IPV4相同

char str[INET6_ADDRSTRLEN];
inet_ntop( AF_INET6, &ipAddr, str, INET6_ADDRSTRLEN );
Run Code Online (Sandbox Code Playgroud)

  • 你忘了将`str`缓冲区传递给`inet_ntop()`.并且`sin_addr`是一个结构 - 必须使用`sin_addr.s_addr`.值得注意的是,IPv4地址以网络字节顺序存储,并将其视为十六进制数字,需要使用`ntohl(pV4Addr-> sin_addr.s_addr)`. (2认同)
  • 这个问题被标记为C - 你不能在`struct sockaddr_in*`这样的类型中省略`struct`.此外,IPV4方法应使用`struct in_addr`而不是`int`来存储地址,与您显示的IPV6方法类似. (2认同)

Mis*_*sha 35

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

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

SoapBox接受的答案对于所有架构都不正确.看Big和Little Endian.


Soa*_*Box 25

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

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

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));
Run Code Online (Sandbox Code Playgroud)

  • 您应该使用inet_ntoa()而不是手动调整位. (29认同)
  • `inet_ntoa`不是线程安全的,虽然这对于大多数使用它的情况可能并不重要.一个安全的替代方案是`inet_ntop`. (13认同)
  • 这不适用于任何大端架构. (6认同)