如果我有一个包含这个字节的缓冲区:
510175126-94-51080
如何从中提取75126-94-51
部分(即IP)并打印正确的IP?
提前致谢。
for(int i = 0; i < bytes_recv; i++)
{
cout << static_cast<int>(temp[i]);
}
cout << endl;
编辑:这是我的输出:5 1 0 1 75 126 -94 -51 0 80
答案 0 :(得分:2)
问题中缺少很多信息。因此,您正在阅读SOCKS协议的服务器回复。首先,缓冲区不应该也不会有10个字节的固定大小。如果您的地址是IPv4(前几天恰好用尽了,是时候考虑IPv6),它有10个字节。如果源具有IPv6地址,则服务器响应的大小不同。
从RFC 1928第6节开始,服务器回复的格式为:
+----+-----+-------+------+----------+----------+ |VER | REP | RSV | ATYP | BND.ADDR | BND.PORT | +----+-----+-------+------+----------+----------+ | 1 | 1 | X'00' | 1 | Variable | 2 | +----+-----+-------+------+----------+----------+
请注意,地址字段的大小可变。对于IPv4,具体来说,ATYP == 0x01和BND.ADDR的大小为4,这使得1 + 1 + 1 + 1 + 4 + 2 = 10个字节。但你应该考虑其他尺寸是可能的,特别是如果ATYP == 0x03,这使得BND.ADDR的长度确实可变。
所以,回答你的问题,考虑到你在char buffer[]
数组(或指针)中有这些字节,你必须首先检查地址的类型,然后像这样提取它:
#include <arpa/inet.h>
switch (buffer[3]) {
case 0x01: { /* IPv4 address */
char result[INET_ADDRSTRLEN];
inet_ntop(AF_INET, (void*)(&buffer[4]), result, sizeof result);
std::cout << "IPv4: " << result << "\n";
break;
}
case 0x04: { /* IPv6 address */
char result[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, (void*)(&buffer[4]), result, sizeof result);
std::cout << "IPv6: " << result << "\n";
break;
}
default:
std::cout << "Unsupported format.\n";
break;
}
答案 1 :(得分:0)
在Python中:
input = '510175126-94-51080'
output = input[4:-3]
print output
答案 2 :(得分:0)
你是如何得到这个缓冲区的?它是struct sockaddr_in
的一部分吗?
您是否显示从缓冲区的最低地址开始的十进制字节转储?
您要做的是获取指向IP地址部分的基址(内存)地址的指针,并使用ntohl()
将其转换为主机字节顺序,同样使用ntohs
来翻译port addr。
修改强>
假设你有
stuct sockaddr_in foo;
char str[16];
// do some stuff that initializes foo, e.g. a call to accept() returns
您可以使用
以点分四方形式提取IP地址inet_ntop(AF_INET, &(foo.sin_addr), str, sizeof(str));
答案 3 :(得分:0)
如果您有以下缓冲区:
buffer[10] = {5, 1, 0, 1, 75, 126, 162, 205, 80, 00};
你想要它在C / C ++中。我会定义一个结构,如下所示:
#pragma pack(1)
struct buffer_s {
uint8_t version;
uint8_t reserve_1;
uint8_t atype;
uint32_t ip;
uint16_t port;
};
#pragma pack()
然后把它放在一个联盟中:
union buffer_u {
char buffer[10];
struct buffer_s data;
};
现在您可以声明union buffer_u buf
并将字节读入buf.buffer。然后,对于ip和port字段,使用ntohl
和ntohs
将网络字节顺序转换为主机字节顺序。