从sockaddr_storage中提取IP地址和端口信息

Rya*_*man 7 c sockets arrays udp ip-address

我目前正在开发一个接收客户端请求的UDP服务器.我收到的数据报是一个5个元素长的字节(char)数组,最后两个元素是一个端口号.

最终,该服务器必须在其自己的数据报中返回IP地址和端口号.

我已经知道如何使用inet_ntop和我连接和接收的sockaddr结构来打印出ip,但它返回的字符串不是我想要的格式.例如:

string1 = inet_ntop(their_addr.ss_family,get_in_addr(
    (struct sockaddr *)&their_addr),s, sizeof s);
Run Code Online (Sandbox Code Playgroud)

收益:

127.0.0.1
Run Code Online (Sandbox Code Playgroud)

要么:

[1][2][7][.][0][.][0][.][1]
Run Code Online (Sandbox Code Playgroud)

当我需要这样的东西:

[127][0][0][1]
Run Code Online (Sandbox Code Playgroud)

我应该使用某种字符和数组操作来制作我的4元素字节数组吗?或者sockaddr是否有这样的信息,我可以把它留在这个十六进制形式并返回它?

小智 13

假设是IPv4.

获取您的sockaddr_storagesockaddr结构的地址并将其转换为IPv4版本后sockaddr_in,您可以访问IPv4地址的各个字节.

struct sockaddr_in *sin = (struct sockaddr_in *)&their_addr;
Run Code Online (Sandbox Code Playgroud)

然后你可以获取s_addr一个32位值的成员的地址(in_addr_t),它保存ip地址的4个字节(按网络字节顺序)并将其转换为指向一个的指针unsigned char然后允许你访问值的各个字节.

unsigned char *ip = (unsigned char *)&sin->sin_addr.s_addr;

printf("%d %d %d %d\n", ip[0], ip[1], ip[2], ip[3]);
Run Code Online (Sandbox Code Playgroud)


Ale*_*ska 5

你想要使用getnameinfo()功能:

int getnameinfo(const struct sockaddr *sa, socklen_t salen,
                   char *host, size_t hostlen,
                   char *serv, size_t servlen, int flags);
Run Code Online (Sandbox Code Playgroud)

例如:

struct sockaddr_storage client_addr;
socklen_t client_len = sizeof(struct sockaddr_storage);

/* Accept client request */
int client_socket = accept(server_socket, 
    (struct sockaddr *)&client_addr, &client_len);

char hoststr[NI_MAXHOST];
char portstr[NI_MAXSERV];

int rc = getnameinfo((struct sockaddr *)&client_addr, 
    client_len, hoststr, sizeof(hoststr), portstr, sizeof(portstr), 
    NI_NUMERICHOST | NI_NUMERICSERV);

if (rc == 0) 
    printf("New connection from %s %s", hoststr, portstr);
Run Code Online (Sandbox Code Playgroud)