2017-07-24 51 views
0

我正在開發一個系統,它包含一個arduino mkr1000,我想通過wifi將數據發送到運行在本地網絡中的java服務器程序。TCP數據有時不被java(或python)服務器接收

一切正常,除了主要部分:通過Arduino的發送的數據有時不通過服務器接收...

我使用arduino Wifi101 library連接到我的無線網絡,得到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讀同樣的事情產生同樣的結果。 測試代碼是隻用簡單的輸出(注意:在科特林):非常標準

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 i.n.handler.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 i.n.handler.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 i.n.handler.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 i.n.handler.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 i.n.handler.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 a b c d e f | 
+--------+-------------------------------------------------+----------------+ 
|00000000| 54 65 73 74 20 32 0d 0a       |Test 2..  | 
+--------+-------------------------------------------------+----------------+ 
11:30:01.449 [nioEventLoopGroup-3-6] WARN i.n.handler.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 i.n.handler.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 i.n.handler.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 i.n.handler.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沒有顯示相同的行爲(但也許我使用了錯誤的選項來顯示重新發送的數據包)。

回答

0

與此同時,我發送消息來確認接收另一條消息。如果未收到確認,則再次發送消息。


對於同樣的問題,任何人:

在測試不同的東西我更新了主板的無線固件19.5.2最新版本。從那以後我沒有注意到任何丟失的數據。也許這是問題所在。 見Check WiFi101 Firmware VersionFirmware and certificates Updater注:我無法使用Arduino IDE運行草圖,但使用PlatformIO