多线程中的recvfrom函数问题: 子线程会收到整个进程接收的报文

yangyi_33855 2014-01-08 07:28:58
多线程部分的逻辑是这样的:
我开了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了整个进程收到的包”是什么原因呢?该如何解决。
...全文
348 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
一枪尽骚丶魂 2014-10-28
  • 打赏
  • 举报
回复
需要确定发送的时候填充的是否为同一个IP和端口,接受的时候如果绑定的是同一个IP和端口,那上面的现象时必然的
空的 2014-01-09
  • 打赏
  • 举报
回复
4个ip就是说这机子有4个网卡接口? 你是同一台机子上收发么? 变量是否有复用的没加锁? 这种分发数据系统是通过套接字对来区分哪个sockid的,应该不会有问题 上代码比较靠谱
dongjiawei316 2014-01-09
  • 打赏
  • 举报
回复
确定两个问题: 1、是否你四个线程对应的IP相同,如果相同,你的想法只能通过不同端口号实现。 2、如果IP不同,那么你给sock_para.sin_addr.s_addr赋值时,用的INADDR_ANY,还是自己的IP?
yangyi_33855 2014-01-08
  • 打赏
  • 举报
回复
我在接受到报文后,将from指向的源地址与子线程发送报文时指定的ip地址比较,如果相等,说明就是该子线程发出的请求报文的应答,这时才算收到,进行后续操作。 但是通过使用这样的方法能实现“a线程只收ip_a的icmp应答报文,b线程………”的效果,但是“子线程收到整个进程接收的报文”这个问题还是存在的。为什么这些讨厌的子线程会也能收到给别人的报文?好痛苦,检查了好久,依然没找到解决问题的正确方法。

23,116

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧