我有一个简单的客户端<>服务器设置,其中客户端每秒多次通过端口 2000 向服务器发送 UDP 数据包。服务器有一个线程,带有一个打开的 BSD 套接字,侦听端口 2000,并使用阻塞recvfrom
调用读取数据。而已。我recvfrom
在服务器中的调用周围设置了一个简单的 tic toc 计时器,并在通过 Wifi 运行时绘制了结果。
当服务器通过 Wifi 连接到接入点时,它的相似之处在于通常 recvfrom 调用也需要 0.015 秒。但是,在没有发送数据包的短时间无线电静默之后(大约半秒),进入服务器的下一个数据包将导致 recvfrom 调用花费极长的时间(在 0.6 到 3 秒之间),然后是一连串非常快速的调用(大约 0.000005 秒)然后恢复正常(大约 0.015 秒)。以下是一些示例数据:
0.017361 <--normal
0.014914
0.015633
0.015867
0.015621
... <-- radio silence
1.168011 <-- spike after period of radio silence
0.000010 <-- bunch of really fast recvfrom calls
0.000005
0.000006
0.000005
0.000006
0.000006
0.000005
0.015950 <-- back to normal
0.015968
0.015915
0.015646
如果您仔细观察,您会在图表上注意到这一点。
当我通过 LAN(即使用电缆)将服务器连接到接入点时,一切正常,recvfrom 调用始终需要大约 0.015 秒。但是通过 Wifi,我得到了这些疯狂的峰值。
这到底是怎么回事?
PS 服务器运行 Mac OS X,客户端是 iPhone,在这两种情况下都通过 Wifi 连接到接入点。我尝试在 iPad 上运行客户端并获得相同的结果。接入点是一个 Apple Airport Extreme 基站,其网络使用 Apple Airport Express 进行扩展。我也尝试过使用 Thompson 路由器和一个简单的(非 WDS 网络),但仍然遇到同样的问题。
更新
我用 C# 重写了 Windows .NET 上的服务器部分,并在 Wifi 上对其进行了测试,保持其他一切不变,问题就消失了。所以它表明这是 Mac OS X 上的操作系统/网络堆栈/套接字问题。