TCP数据有时不被java(或python)服务器接收

我正在开发一个由arduino mkr1000组成的系统,我想通过wifi发送数据到我的本地网络中运行的java服务器程序。

除了主要部分之外的一切工作:由arduino发送的数据有时不被服务器接收…

我正在使用arduino Wifi101库连接到我的wifi,获得WiFiClient并发送数据。 下面的代码只是一个演示问题的例子:

 for (int i = 0; i < 3; ++i) { Serial.println(F("Connecting to wifi")); const auto status = WiFi.begin("...", "..."); if (status != WL_CONNECTED) { Serial.print(F("Could not connect to WiFi: ")); switch (status) { case WL_CONNECT_FAILED: Serial.println(F("WL_CONNECT_FAILED")); break; case WL_DISCONNECTED: Serial.println(F("WL_DISCONNECTED")); break; default: Serial.print(F("Code ")); Serial.println(status, DEC); break; } } else { Serial.println(F("WiFi status: WL_CONNECTED")); WiFiClient client; if (client.connect("192.168.0.102", 1234)) { delay(500); client.print(F("Test ")); client.println(i, DEC); client.flush(); Serial.println(F("Data written")); delay(5000); client.stop(); } else { Serial.println(F("Could not connect")); } WiFi.end(); } delay(2000); } 

java服务器基于Netty,但手动创建和读取Socket的结果相同。 测试代码非常标准,只有一个简单的输出(注意:在Kotlin中):

 val bossGroup = NioEventLoopGroup(1) val workerGroup = NioEventLoopGroup(6) val serverFuture = ServerBootstrap().run { group(bossGroup, workerGroup) channel(NioServerSocketChannel::class.java) childHandler(object : ChannelInitializer<NioSocketChannel>() { override fun initChannel(ch: NioSocketChannel) { ch.pipeline() .addLast(LineBasedFrameDecoder(Int.MAX_VALUE)) .addLast(StringDecoder()) .addLast(object : ChannelInboundHandlerAdapter() { override fun channelRead(ctx: ChannelHandlerContext, msg: Any) { println("msg = $msg") ctx.close() } }) } }) bind(port).sync() } 

arduino告诉你一切正常(比如每次迭代写Data written到串行控制台),但服务器有时会跳过单个消息。 从Netty添加LoggingHandler告诉我在这些情况下:

 11:28:48.576 [nioEventLoopGroup-3-1] WARN inhandler.logging.LoggingHandler - [id: 0x9991c251, L:/192.168.0.20:1234 - R:/192.168.0.105:63845] REGISTERED 11:28:48.577 [nioEventLoopGroup-3-1] WARN inhandler.logging.LoggingHandler - [id: 0x9991c251, L:/192.168.0.20:1234 - R:/192.168.0.105:63845] ACTIVE 

在收到消息的情况下,它告诉我:

 11:30:01.392 [nioEventLoopGroup-3-6] WARN inhandler.logging.LoggingHandler - [id: 0xd51b7bc3, L:/192.168.0.20:1234 - R:/192.168.0.105:59927] REGISTERED 11:30:01.394 [nioEventLoopGroup-3-6] WARN inhandler.logging.LoggingHandler - [id: 0xd51b7bc3, L:/192.168.0.20:1234 - R:/192.168.0.105:59927] ACTIVE 11:30:01.439 [nioEventLoopGroup-3-6] WARN inhandler.logging.LoggingHandler - [id: 0xd51b7bc3, L:/192.168.0.20:1234 - R:/192.168.0.105:59927] READ: 8B +-------------------------------------------------+ | 0 1 2 3 4 5 6 7 8 9 abcdef | +--------+-------------------------------------------------+----------------+ |00000000| 54 65 73 74 20 32 0d 0a |Test 2.. | +--------+-------------------------------------------------+----------------+ 11:30:01.449 [nioEventLoopGroup-3-6] WARN inhandler.logging.LoggingHandler - [id: 0xd51b7bc3, L:/192.168.0.20:1234 - R:/192.168.0.105:59927] CLOSE 11:30:01.451 [nioEventLoopGroup-3-6] WARN inhandler.logging.LoggingHandler - [id: 0xd51b7bc3, L:/192.168.0.20:1234 ! R:/192.168.0.105:59927] READ COMPLETE 11:30:01.453 [nioEventLoopGroup-3-6] WARN inhandler.logging.LoggingHandler - [id: 0xd51b7bc3, L:/192.168.0.20:1234 ! R:/192.168.0.105:59927] INACTIVE 11:30:01.464 [nioEventLoopGroup-3-6] WARN inhandler.logging.LoggingHandler - [id: 0xd51b7bc3, L:/192.168.0.20:1234 ! R:/192.168.0.105:59927] UNREGISTERED 

根据我的理解,这意味着确实收到了TCP数据包,但是在出现故障的情况下,Netty的IO线程正在等待读取TCP数据,但是永远不会继续…使用基本的python服务器尝试时也存在同样的问题用于连接和打印所接收的数据)。

我确认数据是通过在Arch Linux上使用tcpflow发送的,参数为-i any -C -g port 1234 。 我甚至在Windows 7机器上尝试过服务器,结果相同(使用SmartSniff确认TCP数据包)。

奇怪地使用Java服务器发送数据总是可重复的接收…

有没有人有任何想法来解决这个问题,至少如何诊断?

PS:也许重要的是要注意,与tcpflow (即在Linux上),我可以看到TCP数据包重新发送到服务器。 这是否意味着服务器正在接收数据包,但没有发送ACK? SmartSniff没有显示相同的行为(但也许我用错误的选项来显示重新发送的数据包)。

与此同时,我发送消息来确认收到另一条消息。 如果未收到确认,则再次发送消息。


对于任何有同样问题的人:

在测试不同的东西的时候,我把板子的wifi固件更新到最新版本19.5.2 。 从那以后,我没有注意到任何丢失的数据。 也许这是问题。 请参阅检查WiFi101固件版本和固件和证书更新程序 。 注意:我无法使用Arduino IDE运行草图,但使用PlatformIO 。