用C / C ++

时间:2017-05-05 11:14:42

标签: c++ c sockets protocols packets

我知道我的数据包是怎样的。它有6个头字段(每个字节1个字节,每个头有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是第一个字节(我只是将我的第一个标题的每个字段(位)转换为十六进制)。

然后,简单地说,我想将它发送到服务器: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]);

我是对的吗?

2 个答案:

答案 0 :(得分:1)

除了错误处理recv的返回值之外,您的代码看起来还不错。

if ((recv(sockfd, buffer, len, 0)) == 0)
    {
        if (errno != 0)
        {
            exit(1);
        }
    }

零返回表示连接正常关闭。没有理由检查errno是否返回零。

返回值-1表示错误。在这种情况下,检查errno

是有意义的

大于零的值表示已接收到字节数。请注意,recv返回的字节数比您要求的少,这是完全正常的。如果您想要接收一定数量的字节,则必须在循环中调用recv

TCP是一种字节流协议,不知道你的&#34;数据包&#34; (真的,消息)开始和结束。

答案 1 :(得分:0)

您的代码似乎不容易出错!

但一个好的做法是:

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中受益,该库旨在用于分布式或并发应用程序。