繁体   English   中英

通过C套接字发送结构

[英]Sending structs over a C socket

我正在编写DNS查询客户端,但无法理解我的数据如何发送以及如何使其正常工作。

在Wireshark中,我收到了许多带有MALFORMED PACKET警告的随机数据,而正在测试的DNS服务器没有响应。 (当前是Google的DNS ... 8.8.8.8)

一段...

typedef struct DNS_HEADER {

    // id to identify the request
    int16_t id;

    // query or response flag; default is 0
    uint8_t qr :1;

    // type of query; default is 0
    uint8_t opcode :4;

    // authoritative answer
    uint8_t aa :1;

    // message was truncated
    uint8_t tc :1;

    // recursion desired; default is yes
    uint8_t rd :1;

    // recursion available
    uint8_t ra :1;

    // unused
    uint8_t z :1;

    // response code
    uint8_t rcode :4;

    // entries in the question section; default is 1
    uint16_t qdcount;

    // resource records
    uint16_t ancount;

    // server resource records (in the authority section)
    uint16_t nscount;

    // resource records (in addl. section)
    uint16_t arcount;

} dns_h;

header->qr = 0;
header->opcode = 0;
...
header->qdcount = htons(1);
...

还有我的信箱

char buffer[sizeof(*header) * sizeof(*question) * 2];
int offset = 0;
memcpy(buffer, header, sizeof(*header));
offset += sizeof(*header);
memcpy(buffer + offset, question, sizeof(*question)); 

ssize_t sent = sendto(sock, buffer, sizeof(buffer), 0, (struct sockaddr *)addr, sizeof(*addr));

我究竟做错了什么? 这是通过套接字发送结构的推荐方法吗? 我已将标题中的大多数字段设置为0,并将任何我设置为1的内容都使用了htons

标头结构有两个问题:

  • z字段是3位,而不是1。因此, rcode字段在应保留的位置还剩两位。
  • 您完全使用位域的事实。 为了实现这一目标,您需要在编译时知道字节序,并且没有可移植的方法来执行此操作。 您最好为所有内容声明一个16位字段(或2个8位字段),并进行位移以读取/写入适当的值。

您没有在头文件的创建位置显示代码,而是在设置字段时确保使用htons ,以使值以网络字节顺序排列。

另外,请仔细查看Wireshark中数据包中的二进制数据。 将其与您输入的值进行比较,看看有什么地方不对。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM