【发布时间】:2020-11-26 05:00:04
【问题描述】:
上下文:
- 我有一个服务器 (Mac Mini) 和一个客户端 (ESP32),它们通过 WifiClient 类的套接字连接进行通信。
- 服务器通过以太网连接到路由器,客户端使用 2.4ghz WiFi 连接到路由器。
- 服务器是用 Kotlin 编写的,并使用默认的 Java 套接字实现。
- 客户端将使用 FastLED 库将颜色分配给 Neopixel LED(分别为 LED 1 和 2)。
为了测试,服务器每秒以 60 次交替模式发送 FF0000|FF0000 和 0000FF|0000FF(作为字符串)。这个测试效果很好,因为如果颜色以每秒 60 次的速度更新,LED 应该看起来是紫色的。如果系统表现不佳,那么我会看到各个颜色。
Client Github Repo 和 Server Github Repo 了解更多上下文。
问题:
我非常清楚地看到蓝色、红色和紫色交替出现。这告诉我某处存在性能问题,但也有短暂时刻它按预期执行。
我的发现:
我一直在记录读取客户端上每条消息所需的时间:
std::string SocketManager::getNextCommand()
{
unsigned long start = micros();
// TODO: Flush isn't working
// flush(): fail on fd 56, errno: 11, "No more processes"
// client.flush();
// We need to read in our next command; wait until command is available.
String message;
while (client.connected() && message.length() == 0)
{
message = client.readStringUntil('\n');
}
unsigned long end = micros();
Serial.print("Time: ");
Serial.println(end - start);
return message.c_str();
}
打印出来的时间通常很好,但我会遇到大约每秒 10 次的周期性峰值。我已将日志添加到 Pastebin here。
当我第一次看到这个时,我以为客户端缓冲区已经饱和了。然后我将服务器上的消息速率降低到每秒 2 次,但我仍然看到消息时间的显着变化。该日志是here。
每当服务器发送消息以验证它是否以正确的速率写入时,我都会打印出系统时间。每秒更新 2 次始终会产生 500 毫秒的间隙,因此我认为排除服务器是合理的。这表明问题出在传输时间或 ESP32(考虑到服务器以指定的时间间隔发布)。
当套接字未激活时,两个设备之间的 ping 为 5-10ms,但当套接字激活时为 50-400+……即使我没有来回发送任何消息!哎呀——即使我完全注释掉客户端的 while 循环(即它立即返回一个空字符串),它也这么高。
问题:
看来我的核心问题是套接字处于活动状态时设备之间的延迟。至少 - 套接字处于活动状态时的 ping 增加似乎在尝试读取下一个命令时延迟增加的范围内。
你认为套接字是这里的主要问题吗?如果是这样 - 为什么?
我觉得奇怪的是,仅仅由于套接字处于活动状态就会发生如此巨大的延迟增加......尤其是在没有来回传输任何大量数据的情况下。
【问题讨论】:
标签: c++ sockets kotlin arduino esp32