丢包问题解决

感谢原链接:https://www.zhihu.com/question/24330843

内容如下:

当网络出现有规律的故障,我们要依靠原理来解释这种现象。

题主的问题可以归纳为:在电脑上使用PPPoE拨号,可以无障碍上网;而使用路由器的PPPoE拨号,出现间歇性的丢包与延迟,问题可以复现,说明问题并不是偶发,而是有规律的。

问题症结可能:
电脑拨号产生一虚拟接口,由于有PPPoE头部封装,自动将虚拟接口MTU 设置成 1492,电脑上的TCP 的MSS 会动态生成 1452,这样可以避免分片,所以网络一路畅通。

路由器拨号也会产生一个MTU= 1492 的虚拟接口,但是电脑不知道该情况,依然发送packet size = 1500 的包到达路由器,路由器只有被迫分片,分片需要耗费CPU资源,对性能的影响非常大,所以当流量上升到一个阀值,路由器处理不过来,会有丢包,同时延迟也会加大。

解决方案:
在电脑上修改MTU -> 1492 或 1480 ( 最好以4个字节为一个单位),重启电脑,问题应该消失。

 

=====================================分割线======================================

实际情况不一定设1492或是1480,或许可能需要更低,至于到底设多少合适?

感谢原(待定?)链接:http://www.xitongcheng.com/jiaocheng/win10_article_34701.html

以管理员身份运行cmd,输入netsh interface ipv4 show subinterfaces查看当前的MTU值

接着按下面格式输入:netsh interface ipv4 set subinterface "连接名" mtu=值 store=persistent  (如:netsh interface ipv4 set subinterface "WLAN" mtu=1440 store=persistent) 按下回车键,出现“确定”提示 则说明修改完成。

 

=====================================分割线======================================

至于到底取1492还是1480还是我这里的1440,要去试,方法如下:

同样先打开命令提示符(管理员), 输入:ping -l 1472 -f www.baidu.com  (探测百度为例),请求将一个不允许分割的 1472 字节的数据包发送出去;

若是出现传输失败,提示需要拆分数据包的情况,则说明当前网络的 MTU 值要比指定的 1472 小,因此我们就适当调小数据包的大小(比如 1450),输入:ping -l 1440 -f www.baidu.com 按下回车键;(发现不行于是又试了1428)

如果出现传输成功,则说明当前网络的 MTU 值比 1440 要大(但是上面设1440就会丢失,所以应该就设1400附近已经可以了)。实测下来(LOL。。)设1440已经几乎不丢包了。

至于为什么不试试更小的数,比如1400或是13XX甚至更小,因为担心影响其他的应用比如出现这种状况:

 

以上。

在 C# 中,网络编程中常见的粘包和丢包问题可以通过以下方式解决: 1. 粘包问题 粘包问题通常是由于发送方在一段时间内连续发送了多个数据包,而接收方在接收数据时没有及时处理导致的。解决粘包问题的一种方法是在发送的数据包中添加特定的分隔符,在接收方根据分隔符将数据包拆分成多个消息。 以下是一个简单的示例,演示了如何使用特定的分隔符解决粘包问题: ```csharp using System; using System.Net.Sockets; using System.Text; class Program { static void Main(string[] args) { // 创建一个 Socket 对象 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 连接服务器 socket.Connect("127.0.0.1", 8888); // 发送数据 string message1 = "Hello,"; string message2 = "World!"; byte[] buffer1 = Encoding.UTF8.GetBytes(message1 + "|"); byte[] buffer2 = Encoding.UTF8.GetBytes(message2 + "|"); socket.Send(buffer1); socket.Send(buffer2); // 接收数据 byte[] buffer = new byte[1024]; int count = socket.Receive(buffer); string response = Encoding.UTF8.GetString(buffer, 0, count); Console.WriteLine(response); // 关闭 Socket 连接 socket.Shutdown(SocketShutdown.Both); socket.Close(); } } ``` 在上面的示例中,我们在发送的数据包中添加了分隔符 `|`,在接收方根据分隔符将数据包拆分成多个消息。这样可以保证每个消息都是完整的,避免粘包问题。 2. 丢包问题 丢包问题通常是由于网络传输中数据包丢失导致的。解决丢包问题的一种方法是在发送的数据包中添加序号,接收方在接收数据时根据序号判断是否有数据包丢失并进行重传。 以下是一个简单的示例,演示了如何使用序号解决丢包问题: ```csharp using System; using System.Net.Sockets; using System.Text; class Program { static void Main(string[] args) { // 创建一个 Socket 对象 Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 连接服务器 socket.Connect("127.0.0.1", 8888); // 发送数据 int seq1 = 1; int seq2 = 2; string message1 = "Hello,"; string message2 = "World!"; byte[] buffer1 = Encoding.UTF8.GetBytes(seq1 + "|" + message1); byte[] buffer2 = Encoding.UTF8.GetBytes(seq2 + "|" + message2); socket.Send(buffer1); socket.Send(buffer2); // 接收数据 byte[] buffer = new byte[1024]; int count = socket.Receive(buffer); string response = Encoding.UTF8.GetString(buffer, 0, count); Console.WriteLine(response); // 关闭 Socket 连接 socket.Shutdown(SocketShutdown.Both); socket.Close(); } } ``` 在上面的示例中,我们在发送的数据包中添加了序号,接收方可以根据序号判断是否有数据包丢失并进行重传。这样可以保证数据的完整性,避免丢包问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值