UDP报文收不到问题排查

UDP报文收不到问题排查,第1张

同事说告警报文没办法接收了, 程序同时向本机发送UDP告警和另外一台机器发送UDP报文,结果显示,本机UDP是正常收到的,远程的机器收不到UDP报文的

程序同时发送到本地应用和远程应用的,虽然是不同的IP和端口,但是是同一个逻辑,所以程序的本身的问题可能性比较小,先测试下是否为网络问题:

首先,我们来看下这个1472是怎么来的,在以太网环境中,以太网的帧的body大小为46字节到1500字节之间,本次是处于IPV4的环境,IP包头大小为20个字节,所以还剩下1480字节;UDP的协议的报文头长度为8个字节,所以剩下的udp的包体长度为1480-8 = 1472个字节,具体展示如下图:

格式如下:

上述告警意思是因为我们环境下网卡的MTU设置为1500个字节,如下:

因为发送的UDP报文长度大于可以传输的安全长度1472个字节,这不代表不能发送,只是因为大于了帧的最大传输长度,所以在IP层需要进行分包,一旦网络环境不好,分包产生了丢失问题,会造成IP的组包失败,从而导致UDP的报文丢失

还可以通过 netstat -su 进行监控:

既然MTU太小了,那么尝试修改下两端的MTU最大值,MTU是取整个路由的MTU最小值,我们尝试把两端的MTU增大下:

两端MTU增加后,仍然会报错,那么可能的原因是中间路由设备设置的MTU比较小,查看下,由于主机上没有traceroute命令来跟踪,尝试使用另外一个命令:

类似于traceroute,可以追踪路由,结束后打印MTU值

还可以带个端口,测试这个UDP端口

在实际环境中,由于中间很多路由都看不到,而且让中间的所有路由都改MTU值不是太现实

在MTU为1500字节的情况下,如果发送的UDP报文大于MTU,比如发送8000个字节,如果包缓存足够,且分包按照正确的顺序到来,通过recvfrom(9000) 还是可以收到一个完整的UDP包的 如果IP分片丢失,校验失败,包就会丢弃recvfrom(9000)将阻塞

为防止socket缓冲区溢出造成的问题,特意增加了socket的缓冲区

cat /proc/sys/net/core/rmem_default 和 cat /proc/sys/net/core/rmem_max 可以查看socket缓冲区的缺省值和最大值。

可以通过 echo xxx >/proc/sys/net/core/rmem_default 的方法来临时修改,也通过更改/etc/sysctlconf文件添加以下配置来修改:

修改完成后记得运行以下命令来生效:

但是在本次仍然没起到效果

最终解决方法是绕过了这个问题,直接改了接口,不采用UDP发送了,而是采用文件采集形式

这是一次不成功的经验,有这方面经验的朋友,可以留言交流下还有什么原因造成这种问题

昨天,接同事电话,说帮忙协查一个UDP抓不到包的问题,他描述的问题是A主机通过UDP协议向B主机的10001端口发送syslog报文,结果我们的采集程序flume收不到数据;但是C主机向B主机的10002端口也同样发送syslog报文,同一个flume采集程序却可以正常收到报文。

B主机双网卡分别为:42这个ip,网口是eth0;72这个ip,网口是eth1。

B对外网用的IP是一个134网段的IP。

A主机和C主机均使用134这个网段的IP向B主机发送报文。

示意图如下:

我第一个反应是不是防火墙的问题。登录到主机后,因为是centos7的版本,所以通过防火墙状态查看命令,查看防火墙已经关闭。

继续分析,接着考虑是不是防火墙的问题,所以在接收主机B主机上用tcpdump进行抓包,命令如下:

发现报文没问题,接着加上-vv选项,可以看到解析出来的信息,也正是我们要发送的报文,说明中间网络是没问题的。

nc可以说是网络测试的神器,可以方面的建立监听端口,做服务器;可以做客户端测试服务器。

具体测试步骤如下:

1 把B上的flume监听程序停止,然后在B主机上 运行一下命令:

结果:收不到任何消息!!! 有点吃惊,都可以抓到包了,防火墙也是关闭的为什么收不到那。

不服气,继续用nc,在B主机随便启动一个10009端口:

在A服务器上 通过nc命令连接测试:

输入报文进行测试,仍然收不到报文。

2 看下系统日志,发现没有报错。

进入深深的思考中

说什么,咱们也不能认怂啊,打电话问了下大师,大师说重启下防火墙吧。

所以第二天一大早联系上同事,继续重启防火墙,发现故障依旧。

接着看下flume启动的监听端口情况:

监听的ip配置为0000 ,端口绑定的是10001 ,没问题。

虽然B主机有两块网卡,两个IP,但是我们监听了所有IP啊,谨慎一点,还是把IP配置成抓包抓到的42这个IP,结果故障依旧。

继续在B主机上抓包,发现A主机过来的IP是10网段,C主机过来的IP是134网段,那说明源IP网段不一样,会不会因为网段问题造成的这个问题。

鬼使神差地,用 route -n 看了下路由信息,发现:

10网段的目标IP,用的是eth1 这个网口,但是这个eth1的网口配置的ip是72 ip和A向B发送的目标IP不同,A向B发送的目标Ip为34这个ip。

下面把UDP包的流转过程梳理下:

从B主机(IP:10xxx)向A主机的134xxx 发送UDP报文,UDP报文经过中间的NAT转换后目标IP变成了xxx42 通过网口eth0进入到B主机。

B主机访问10xxx 时候,按照现有的route配置,是通过eth1 网口出去的,如果要是有回包的话,那么接收包的网口eth0和回包的网口eth1 不是同一个网卡!

总觉得不太对,我手工删除老的10xxx 路由,并且添加了下新的路由,新路由走eth0,命令如下:

接着再次测试nc收包情况,却可以收到了,flume也同样可以收到了,至此问题解决。

但是有点想不通,按道理udp报文是不会受到目录路由影响的,有大神知道的,请告知。

12端口就用12个线程去接收。 但处理都是一样的吧。

所以要有个事件 比如定义一个事件

public delegate void DataArrivalHandler(byte[] data);参数你定,或者(Stream s)之类,也可以是自定一个类(包含其它信息)继承EventArgs写个 (DataEventArgs e)

public event DataArrivalHandler OnDataArrived;

OnDataArrived+=()这里注册相应的方法,如果不同端口的处理不一样,就相应写不同的事件,当然也可以只定义一个方法,方法根据不同的端口处理。

while(true)

{

byte[] data = (获取)

这里获取数据后,直接调用

OnDataArrived(data)/OnDataArrived(stream)/OnDataArrived(new DataEventArgs (data,ip,port)之类,根据你定义的参数来。

}

而注册的方法里的具体实现,用委托异步调用 方法体里执行

{

namedDelegatebeginEnvoke();

}

这样,数据处理就异步完成了。

避免数据丢失的话,做个保险。 把接收的数据放入定义的缓冲块里。 当接收的数据量到达一定程序后,取出部分处理,再加入新数据。

类似于TCP的的滑动窗口。 麻烦点,但实现了,效果会好的多。

--------------------------

为什么要用ThreadPool? 不便于控制状态。 当你的线程处理的业务非常单一时用它,这种情况需要不需额外的状态信息,比如就像你上面的每次有不同的byte[] data。

直接 new ThreadStart();

UDP工作原理:udp用户数据报协议 (RFC 768)

用户数据报协议(UDP)是 OSI 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。 UDP 协议基本上是 IP 协议与上层协议的接口。 UDP 协议适用端口分别运行在同一台设备上的多个应用程序。

由于大多数网络应用程序都在同一台机器上运行,计算机上必须能够确保目的地机器上的软件程序能从源地址机器处获得数据包,以及源计算机能收到正确的回复。这是通过使用 UDP 的“端口号”完成的。

UDP协议使用IP层提供的服务把从应用层得到的数据从一台主机的某个应用程序传给网络上另一台主机上的某一个应用程序。

UDP协议有如下的特点:

1、UDP传送数据前并不与对方建立连接,即UDP是无连接的,在传输数据前,发送方和接收方相互交换信息使双方同步。

2、UDP不对收到的数据进行排序,在UDP报文的首部中并没有关于数据顺序的信息(如TCP所采用的序号),而且报文不一定按顺序到达的,所以接收端无从排起。

3、UDP对接收到的数据报不发送确认信号,发送端不知道数据是否被正确接收,也不会重发数据。

4、UDP传送数据较TCP快速,系统开销也少。

UDP 适用于不需要 TCP 可靠机制的情形,比如,当高层协议或应用程序提供错误和流控制功能的时候。 UDP 是传输层协议,服务于很多知名应用层协议,包括网络文件系统(NFS)、简单网络管理协议(SNMP)、域名系统(DNS)以及简单文件传输系统(TFTP)。

以上就是关于UDP报文收不到问题排查全部的内容,包括:UDP报文收不到问题排查、一次UDP收不到包的问题排查、如何 监听,接收 所有UDP端口 数据等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/9575963.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-29
下一篇 2023-04-29

发表评论

登录后才能评论

评论列表(0条)

保存