MikeWang000000 / Natter

Expose your TCP/UDP port behind full-cone NAT to the Internet.
GNU General Public License v3.0
1.64k stars 137 forks source link

A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself. #88

Open zaiqixiao opened 6 months ago

zaiqixiao commented 6 months ago

Discussed in https://github.com/MikeWang000000/Natter/discussions/87

Originally posted by **zaiqixiao** May 9, 2024 使用gost方法转发 ![QQ截图20240509123830](https://github.com/MikeWang000000/Natter/assets/166514485/fe15eadd-cdac-4b9d-95ce-bd7c073e3521) 似乎是缓冲区过小,这个该如何解决。 还有一个问题我用socket使用UDP协议延迟波动很大似乎是丢包,改用gost能改善这个问题吗? 请佬帮帮
MikeWang000000 commented 6 months ago

Natter 的 socket 转发方法内的 UDP buffer 大小目前固定为 8192,如果收到的 UDP 数据包的内容大于这个值,就会被丢弃(丢包)。

可以手动把这个值改大,再试试情况是否有改善:

https://github.com/MikeWang000000/Natter/blob/27d7c1d18ae70a2d6027b843ed162e3f4e28a818/natter.py#L887

Gost 的缓冲区大小不太清楚,看起来也是超过了限制。

想问一下您的使用场景?以及 MTU 值是否设置的比较大。

zaiqixiao commented 6 months ago

目前主要是UDP协议的游戏服务器比如(饥荒、七日杀),还有N2N。手动改大缓冲区会有什么影响吗?比如cpu利用率会变高?我以为gost缓冲区是natter带参执行的,但是我也稍微翻了一下代码没看到相关的。MTU值我记得代码里面好像是默认1500。使用socket就经常出现:【fwd-socket: socket send thread is exiting: timed out】

MikeWang000000 commented 6 months ago

我这里暂时没有找到 Gost 配置缓冲值的方法,Natter 也确实没有将缓冲值参数带给 Gost。


Natter socket 转发相关:

可以同时调一调这两个值看看是否有所改善。


以后 Natter 也会考虑将超时时间设置为命令行选项,方便修改。

zaiqixiao commented 6 months ago

好的谢谢佬,我先改成32kb试试看。

zaiqixiao commented 6 months ago

增大缓冲区确实会有所改善,不过我发现缓冲区设置成1MB跟2MB后性能似乎没有什么改变。我是通过工具不断向UDP端口发送数据,每发送100次总会有10次左右没有返回延迟,不知道是什么原因。每个包是64字节。超时时间我调成了120。我想知道这些数值有没有一个比较推荐的平衡值。或者说有没有更好的方法可以测试性能。

zaiqixiao commented 6 months ago

QQ截图20240521132124 会出现有规律性的超时,buffer size是1MB,超时时间是300。

MikeWang000000 commented 6 months ago

是否是针对公网的 UDP 端口进行的测试?此时已经过运营商,UDP 可能会受 QoS 策略影响而偶发丢包。


关于性能,-m socket 不是一种高性能的方法,而是一种“有 Python 就能跑”的一种兼容性考虑,适用于对延迟不是很敏感的场景。

性能最高的是 Linux 下的 -m iptables,并且不存在配置缓冲区的问题,因为是内核直接处理,而不是在应用层复制转发一遍。可惜 Windows 下缺少类似方法。

Windows 下还可以使用 -m socat,另一种工具。它在 Linux/Unix 上常见,也有移植到 Windows 的版本: https://sourceforge.net/projects/unix-utils/files/socat/1.7.3.2/

zaiqixiao commented 6 months ago

[是针对公网的端口测试。因为我对这几种转发并没有很深刻的认识,不过根据查阅的资料说gost作为协程更适合处理I/O所以一开始是想尝试gost。我会尝试使用socat测试一下。谢谢佬] QQ截图20240522144425 不过我在gost的参考方法中有看到一个readBufferSize不知道是不是等同于socket的buffersize呢

MikeWang000000 commented 6 months ago

是的,不过只适用于gost v3。

如果使用的是 v3 版本,可以改一下这里:

https://github.com/MikeWang000000/Natter/blob/27d7c1d18ae70a2d6027b843ed162e3f4e28a818/natter.py#L810

"?ttl=%ds" 改成 "?ttl=%ds&readBufferSize=65535" 或其他值,试试效果。

zaiqixiao commented 6 months ago

调整之后遇到一个问题,测试UDP端口时延迟波动比较大,使用gost转发N2N的UDP端口。两台设备之间无法ping通。 QQ截图20240523104827 QQ截图20240523101723 补充:防火墙都关闭尝试过。这张截图没关闭。 使用socat的话就正常 QQ截图20240523101952 还有windows下能否用netsh实现端口转发

MikeWang000000 commented 6 months ago

netsh 在各版本 Windows 上的功能各不相同;Server 版可以达到类似 Linux iptables 的效果,但是很少有人用到,也就没有做。 一般版本,使用 portproxy 的话只能转发 TCP,是不支持 UDP 的。并且它会独占端口,Natter 不能复用。

gost 转发的问题,只能调参数试试了,比如 gost udp 下的 keepalive 参数等等。不确定它的实际效果如何。

zaiqixiao commented 6 months ago

好的谢谢佬