在 C/C++ 中创建和发送原始数据包
Creating and sending raw data packets in C/C++
我知道我的包裹是什么样子的。它有 6
header 个字段(每个 1 个字节,每个 header 有 8 个字段)然后它有有效负载(数据)。
我想用 C 或 C++ 构建一个原始数据包(我认为它应该看起来一样)。
这是我认为我应该做的:
unsigned char packet[11];
packet[0] = (0x81); // first header with 8 fields
packet[1] = (0x8c); // second header with 8 fields
packet[2] = (0xfe);
packet[3] = (0x84);
packet[4] = (0x1d);
packet[5] = (0x79);
packet[6] = (0x96); // payload, the 'h' letter, masked
packet[7] = (0xe1); // 'e'
packet[8] = (0x71); // 'l'
packet[9] = (0x15); // 'l'
packet[10] = (0x91);// 'o'
例如,0x81
是第一个字节(我只是将第一个 header 的每个字段(位)转换为十六进制)。
然后,简单地说,我想将它发送到服务器:send(sockfd, packet, sizeof(packet), 0)
来发送它。
接收并打印响应:
unsigned char buffer[1024];
if ((recv(sockfd, buffer, len, 0)) == 0)
{
if (errno != 0)
{
exit(1);
}
}
int i;
for(i = 0; i<len; i++)
printf("%x ", buffer[i]);
我说的对吗?
您的代码不会出现错误!
但一个好的做法是:
const std::uint32_t BUFFER_SIZE = 11;
std::vector<std::uint8_t> buffer;
buffer.reserve(BUFFER_SIZE)
buffer = {0x81,0x8c.....};
send( sockfd,
reinterpret_cast <const char*> ( buffer.data() ),
static_cast <int> ( buffer.size() ),
0
);
这样做,您的代码会得到更优化,并避免可能的泄漏,使用 std
向量。
查看 ZeroMQ 也可能会受益,将其作为现成的高性能异步消息传递库的示例,旨在用于分布式或并发应用程序。
除了错误处理 recv
中的 return 值外,您的代码看起来还不错。
if ((recv(sockfd, buffer, len, 0)) == 0)
{
if (errno != 0)
{
exit(1);
}
}
零return表示连接正常关闭。如果 return 为零,则没有理由检查 errno
。
-1
的 return 值表示错误。在这种情况下,检查 errno
.
确实有意义
大于零的值表示已收到字节数。请注意,recv
到 return 个字节比您要求的少是完全正常的。如果您想准确接收一定数量的字节,则必须在循环中调用 recv
。
TCP 是一种字节流协议,不知道您的 "packets"(实际上是消息)的开始和结束位置。
我知道我的包裹是什么样子的。它有 6
header 个字段(每个 1 个字节,每个 header 有 8 个字段)然后它有有效负载(数据)。
我想用 C 或 C++ 构建一个原始数据包(我认为它应该看起来一样)。
这是我认为我应该做的:
unsigned char packet[11];
packet[0] = (0x81); // first header with 8 fields
packet[1] = (0x8c); // second header with 8 fields
packet[2] = (0xfe);
packet[3] = (0x84);
packet[4] = (0x1d);
packet[5] = (0x79);
packet[6] = (0x96); // payload, the 'h' letter, masked
packet[7] = (0xe1); // 'e'
packet[8] = (0x71); // 'l'
packet[9] = (0x15); // 'l'
packet[10] = (0x91);// 'o'
例如,0x81
是第一个字节(我只是将第一个 header 的每个字段(位)转换为十六进制)。
然后,简单地说,我想将它发送到服务器:send(sockfd, packet, sizeof(packet), 0)
来发送它。
接收并打印响应:
unsigned char buffer[1024];
if ((recv(sockfd, buffer, len, 0)) == 0)
{
if (errno != 0)
{
exit(1);
}
}
int i;
for(i = 0; i<len; i++)
printf("%x ", buffer[i]);
我说的对吗?
您的代码不会出现错误!
但一个好的做法是:
const std::uint32_t BUFFER_SIZE = 11;
std::vector<std::uint8_t> buffer;
buffer.reserve(BUFFER_SIZE)
buffer = {0x81,0x8c.....};
send( sockfd,
reinterpret_cast <const char*> ( buffer.data() ),
static_cast <int> ( buffer.size() ),
0
);
这样做,您的代码会得到更优化,并避免可能的泄漏,使用 std
向量。
查看 ZeroMQ 也可能会受益,将其作为现成的高性能异步消息传递库的示例,旨在用于分布式或并发应用程序。
除了错误处理 recv
中的 return 值外,您的代码看起来还不错。
if ((recv(sockfd, buffer, len, 0)) == 0)
{
if (errno != 0)
{
exit(1);
}
}
零return表示连接正常关闭。如果 return 为零,则没有理由检查 errno
。
-1
的 return 值表示错误。在这种情况下,检查 errno
.
大于零的值表示已收到字节数。请注意,recv
到 return 个字节比您要求的少是完全正常的。如果您想准确接收一定数量的字节,则必须在循环中调用 recv
。
TCP 是一种字节流协议,不知道您的 "packets"(实际上是消息)的开始和结束位置。