从sockaddr_storage中提取IP地址和端口信息
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从sockaddr_storage中提取IP地址和端口信息相关的知识,希望对你有一定的参考价值。
我目前正在开发一个接收客户端请求的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);
收益:
127.0.0.1
要么:
[1][2][7][.][0][.][0][.][1]
当我需要这样的东西:
[127][0][0][1]
我应该使用某种字符和数组操作来制作我的4元素字节数组吗?或者sockaddr是否有这样的信息,我可以把它留在这个十六进制形式并返回它?
假设是IPv4。
在获取sockaddr_storage
或sockaddr
结构的地址并将其转换为IPv4版本sockaddr_in
之后,您可以访问IPv4地址的各个字节。
struct sockaddr_in *sin = (struct sockaddr_in *)&their_addr;
然后你可以获取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
", ip[0], ip[1], ip[2], ip[3]);
你想要使用getnameinfo()
函数:
int getnameinfo(const struct sockaddr *sa, socklen_t salen,
char *host, size_t hostlen,
char *serv, size_t servlen, int flags);
Ef。:
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);
这是一个简单的不可变类,我用于你在问题中提到的相同目的:
class address_t {
private:
uint16_t m_Port = 0;
std::string m_Ip = "";
public:
address_t(const sockaddr_in & address) {
m_Ip = inet_ntoa(address.sin_addr);
m_Port = ntohs(address.sin_port);
}
uint16_t GetPort() const { return m_Port; }
std::string GetIp() const { return m_Ip; }
std::string ToString() const {
return "IP: " + m_Ip + ", Port: " + std::to_string(m_Port);
}
};
以上是关于从sockaddr_storage中提取IP地址和端口信息的主要内容,如果未能解决你的问题,请参考以下文章
如何理解存储在 sockaddr_storage 中的 IP 的 IP 版本
将 IPv4/IPv6 地址和端口设置为 sockaddr_storage 结构
将 sockaddr_storage 转换为 inet_ntop 的 sockaddr_in