原始 UDP 套接字卡在 recvfrom 上

Posted

技术标签:

【中文标题】原始 UDP 套接字卡在 recvfrom 上【英文标题】:Raw UDP socket get stuck on recvfrom 【发布时间】:2013-03-20 19:44:38 【问题描述】:

我正在通过原始套接字发送 dns 数据包(类型 A)。我从我的默认 DNS 服务器获得了很好的结果 问题是我的代码卡在“recvfrom”中,我可以通过wireshark看到传出的请求数据包和传入的答案(没有错误)。我尝试了各种操作,例如使用不同的套接字来传出和传入数据包,尝试“recv”……但似乎没有任何效果。我将不胜感激。

int main() 
char hostname[100];

//Get the DNS servers from the resolv.conf file
get_dns_servers();
struct sockaddr_in sin;
// dest
sin.sin_family = AF_INET;
sin.sin_port = htons (53);
sin.sin_addr.s_addr = inet_addr (dns_servers[0]);

//Get the hostname from the terminal
cout << "\nEnter Hostname to Poison : ";
scanf("%s" , hostname);


//Create a raw socket of type IPPROTO
int s = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);

if(s == -1)

    //socket creation failed, may be because of non-root privileges
    perror("Failed to create raw socket");
    exit(1);


dns_packet *pak = new dns_packet("192.168.203.128",(uint16_t) 50115,(in_addr_t) sin.sin_addr.s_addr, (in_port_t) sin.sin_port, (int) 3333, hostname);

//Send the packet
if (sendto (s, pak->datagram, pak->iph->tot_len ,   0, (struct sockaddr *) &sin, sizeof (sin)) < 0)

    perror("sendto failed");

//Data send successfully
else

    printf ("Packet Send. Length : %d \n" , pak->iph->tot_len);


//Receive the answer
int i = sizeof(sin);
unsigned char buf[65536];

cout << "\nReceiving answer..." << endl;
if(recvfrom (s,(char*)buf , sizeof(buf) , 0 , (struct sockaddr*)&sin , (socklen_t*)&i ) < 0)

    perror("recvfrom failed");


read_answer(buf);

return 0;

【问题讨论】:

感谢@2to1mux,我终于成功了。我在某处读到我无法将端口绑定到原始套接字(绑定是传输层概念)。而且我在wireshark目标端口无法访问,所以我为传入的数据包打开了另一个套接字并将套接字绑定到我的传入数据包目标端口。谢谢! 【参考方案1】:

在您的代码中没有调用绑定。你需要绑定一个接口才能接收到任何东西。

编辑:另外,我注意到您使用的是原始套接字。使用原始套接字时,通常使用 recvmsg() 而不是 recvfrom() 更容易。这是 recvmsg() 的链接:http://www.developer.nokia.com/Community/Wiki/Open_C_Sockets:_recv,_recvfrom,_recvmsg_methods

【讨论】:

以上是关于原始 UDP 套接字卡在 recvfrom 上的主要内容,如果未能解决你的问题,请参考以下文章

在 UDP 套接字上使用 sendto()/recvfrom() 而不是 connect()/send()/recv() 的目的是啥?

将 recvfrom() 与原始套接字一起使用:一般疑问

【奇】udp的recvfrom

UDP和套接字,recvfrom()返回-1,资源暂时不可用

2-3:套接字(Socket)编程之UDP通信,sockaddr,sockaddr_in,recvfrom,sendto

关于socket通信UDP协议的问题,在客户端client下创建两个套接字s、s1分别用于recvfrom()和sendto()。