免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4286 | 回复: 6
打印 上一主题 下一主题

[网络] 多线程中的recvfrom函数问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-01-08 19:24 |只看该作者 |倒序浏览
多线程部分的逻辑是这样的:
我开了4个线程:
线程A: 1. 创建socket sockA, 2. bind 到设备的ip上,开始死循环(3. 用sendto向目的ip ip_a发icmp请求报文,4. 用recvfrom接受收到的报文)。(ip_a是我电脑的ip,抓包用)
线程B: 1. 创建socket sockB, 2. bind 到设备的ip上,开始死循环(3. 用sendto向目的ip ip_b发icmp请求报文,4. 用recvfrom接受收到的报文)。(ip_b是一个ping不通的ip)
线程C: 1. 创建socket sockC, 2. bind 到设备的ip上,开始死循环(3. 用sendto向目的ip ip_c发icmp请求报文,4. 用recvfrom接受收到的报文)。(ip_c能通)
线程D: 1. 创建socket sockD, 2. bind 到设备的ip上,开始死循环(3. 用sendto向目的ip ip_d发icmp请求报文,4. 用recvfrom接受收到的报文)。(ip_d能通)

这几个线程,都是调用的同一函数: void *func(){(逻辑1)、(逻辑2)、(逻辑3)、(逻辑4)}

执行结果:
1. 在电脑上通过wireshark能抓到报文,dip、sip、个数(有多少个请求的就有多少个应答的)、长度都正确。(注意:wireshark没抓到其他线程需要的应答报文,但是通过程序解析recvfrom函数的第二个参数和打印查看第5个参数(struct sockaddr *)&from,发现还收到了源IP为ip_c、ip_d的报文);
2. 线程B能收到报文,程序里解析报文内容并打印出来一看,发现,收到的报文的源ip有ip_a、ip_c、ip_d的。
3. 线程C能收到报文,除了ip_c,还有ip_a、ip_d的
4. 线程D能收到报文,除了ip_d,还有ip_a、ip_c的

分析:
1. 从执行结果1来看,程序发包部分,应该没问题,wireshark没有出现线程A 发ip_b\ip_c\ip_d的icmp请求包和收到ip_b\ip_c\ip_d的icmp应答包。
2. 从程序打印信息来看,每个线程调用recvfrom函数能收到的整个进程收到的应答报文,没有达到“a线程只收ip_a的icmp应答报文,b线程…………”的效果。

因此,在这里请教各位大侠,出现“子线程recvfrom了整个进程收到的包”是什么原因呢?该如何解决。

论坛徽章:
0
2 [报告]
发表于 2014-01-08 19:34 |只看该作者
我在接受到报文后,将from指向的源地址与子线程发送报文时指定的ip地址比较,如果相等,说明就是该子线程发出的请求报文的应答,这时才算收到,进行后续操作。
但是通过使用这样的方法能实现“a线程只收ip_a的icmp应答报文,b线程………”的效果,但是“子线程收到整个进程接收的报文”这个问题还是存在的?好痛苦,检查了好久,依然没找到解决问题的正确方法

论坛徽章:
0
3 [报告]
发表于 2014-01-08 19:48 |只看该作者
哦,我的sendto/recvfrom的第一个参数socket都是用的各个子线程的。
以线程A为例:recvfrom(sockA, packet, sizeof(packet), 0, (struct sockaddr *)&from,
                    &fromlen);
                    sendto(sockB, packet, sizeof(packet), 0, (struct sockaddr *)&ip_a->sin_addr,
                    sizeof(struct sockaddr_in));
                  
      

论坛徽章:
0
4 [报告]
发表于 2014-01-08 19:52 |只看该作者
上面sendto写错了,是sendto(sockA, packet, sizeof(packet), 0, (struct sockaddr *)&ip_a->sin_addr,
                     sizeof(struct sockaddr_in));
哎,头晕眼花的,休息会儿

论坛徽章:
4
白羊座
日期:2013-09-17 21:59:30技术图书徽章
日期:2013-10-12 22:16:03白羊座
日期:2013-10-14 11:01:40双子座
日期:2013-12-17 18:26:39
5 [报告]
发表于 2014-01-08 20:18 |只看该作者
你可以试试unp上说的调用connect的方法,不过在我的系统的文档上没有看到相关的说明(man -s 7 raw)

论坛徽章:
0
6 [报告]
发表于 2014-01-09 09:44 |只看该作者
井蛙夏虫 发表于 2014-01-08 20:18
你可以试试unp上说的调用connect的方法,不过在我的系统的文档上没有看到相关的说明(man -s 7 raw)

!按照你说的,我在bind之后,再connect,终于是解决这个问题了。为什么使用connect之后(我什么都没改,socket的属性都没动,就在bind函数后加connect函数),某子线程的recvfrom会收不到其他线程的报文呢?还得学习学习,搞透它,谢谢啦!

论坛徽章:
0
7 [报告]
发表于 2014-01-19 11:52 |只看该作者
楼主搞透没有啊,分享分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP