【问题标题】:recv function gets stuck even if send is successfull即使发送成功,recv 函数也会卡住
【发布时间】:2019-10-17 13:15:33
【问题描述】:

我正在尝试将 dns 查询发送到 dns 服务器。 即使我的发送函数正在工作,但 recv 函数不返回任何 this。 它也没有给出任何错误。 它在“接收答案....”行之后卡住了

struct sockaddr_in dest;

dest.sin_family = AF_INET;
dest.sin_port = htons(53);
dest.sin_addr.s_addr = inet_addr("208.67.222.222"); //dns servers

int s;
s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP);


int query_size=sizeof(struct DNS_HEADER) + (strlen((const char*)domain)+1) + 4;
printf("\n\nquery size - %d",query_size);

int cs=connect(s,(struct sockaddr*)&dest,sizeof(dest));
if(cs==0)
{
    printf("\n\nconnect success\n\n");
}
printf("\nSending Packet...");
if( send(s,(char*)buf,query_size,0) < 0)
{
    perror("sendto failed");
}
printf("Done");

//Receive the answer
i = sizeof(struct sockaddr_in);
printf("\nReceiving answer...");

if(recv(s,(char*)buf , 65536,0) < 0)
{
    perror("recvfrom failed");
}
printf("Done");

【问题讨论】:

  • 另一端在做什么?你确定它正在发送响应?您发送的请求是否正确?
  • 为什么要连接到 UDP 服务? UDP 是一种未连接 协议。对于 UDP,你通常将本地套接字绑定到本地地址,然后使用 sendtorecvfrom 发送和接收数据包。
  • @Someprogrammerdude 您可以将connect() 与UDP 套接字一起使用;它设置通过write()send() 等不明确包含地址的系统调用发送数据时使用的默认地址。它还将套接字限制为仅接收来自该地址的数据报。
  • buf 的内容是什么?可能 DNS 服务器没有响应,因为 DNS 查询无效。
  • 如果您使用另一个工具/客户端(如dig)从同一主机尝试相同的查询会发生什么?在您的情况下,如果您查看网络级别(使用wiresharktcpdump),您会看到回复吗?你需要显示你的“buf”的内容,你是怎么生成的?您是否多次阅读 RFC 1034 和 1035 以清楚地了解 DNS 数据包是如何形成的?对于本地开发,您应该安装一个仅对您的主机开放的本地递归 DNS 服务器并针对它调试您的程序,这样查看两端发生的事情会简单得多。

标签: c sockets dns


【解决方案1】:

我已经解决了这个问题。问题出在我的 dns 标头结构中。我是这样声明的

struct DNS_HEADER
{
    unsigned short id;

    unsigned char qr :1;
    unsigned char opcode :4;
    unsigned char aa :1;
    unsigned char tc: 1;
    unsigned char rd: 1;
    unsigned char ra: 1;
    unsigned char z :3;
    unsigned char rcode :4;

    unsigned short qdcount;

    unsigned short ancount;

    unsigned short nscount;

    unsigned short arcount;

};

这里的问题是。标志字节没有按网络字节顺序转换。当我重新排列结构变量时它起作用了。

struct DNS_HEADER
{
    unsigned short id; // identification number

    unsigned char rd :1; // recursion desired
    unsigned char tc :1; // truncated message
    unsigned char aa :1; // authoritive answer
    unsigned char opcode :4; // purpose of message
    unsigned char qr :1; // query/response flag

    unsigned char rcode :4; // response code
    unsigned char cd :1; // checking disabled
    unsigned char ad :1; // authenticated data
    unsigned char z :1; // its z! reserved
    unsigned char ra :1; // recursion available

    unsigned short qdcount; // number of question entries
    unsigned short ancount; // number of answer entries
    unsigned short nscount; // number of authority entries
    unsigned short arcount; // number of resource entries
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 1970-01-01
    • 2017-01-03
    • 2023-03-15
    • 1970-01-01
    • 2018-04-02
    • 2018-05-28
    相关资源
    最近更新 更多