簡體   English   中英

從客戶端套接字讀取數據似乎缺少字節(從Java到python)

[英]Read data from a client socket seems miss bytes (from java to python)

背景

我最近才剛剛開始學習網絡和Google的協議緩沖區,以在Java客戶端與python服務器之間建立通信。 從我的python服務器向Java客戶端發送消息的過程完美,但是相反的方式(從Java到python)始終失敗。

問題

在從雙方檢查了消息的長度之后,我發現接收器(python)缺少了Java代碼傳輸的某些字節,

Java端:
12 28 08 0b 12 24 15 00 00 80 3f 1a 1b 09 00 00 00 00 00 00 f0 3f 11 00 00 00 00 00 00 00 00 f0 3f 19 00 00 00 00 00 00 00 f0 3f 22 00
python端:
12 28 08 0b 12 24 15 00 00 80 3f 1a 1b 09 00 00 00 00 00 00 f0 3f 11 00 00 00 00 00 00 00 f0 3f

如您所見,最后10個字節丟失了。 我不知道問題所在。

代碼

以下是我的java代碼,

// Both Message and UPDATEs are message types I defined in my .proto file
Message message = Message.newBuilder()
                        .setUpdate(UPDATEs.newBuilder()
                        .setTimeStamp(11)
                        .addUpdates(state))
                        .build();
//System.out.println(message.toString());
System.out.println(message.toByteArray().length); // result -> 42
//System.out.println(byteArrayToHex(message.toByteArray()));
try {   
    OutputStream outputStream = socket.getOutputStream();
    message.writeDelimitedTo(outputStream);     
    System.out.println("Sending finished.");
} catch (IOException e) {
    System.err.println("SteerCommunicator_sendCarData(OutputStream output): " + e.toString());
    System.exit(0);
}

還有我的python代碼

def server_loop():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "Listening at port {}".format(PORT)
try:
    server.bind(("localhost", PORT))
except:
    print "Unable to listen on the Port" + PORT
    sys.exit()

server.listen(10)

while True:
    client_socket, addr = server.accept()
    print "Received Message from Client {}:{}".format(addr[0],str(addr[1]))
    msg = client_socket.recv(1024)
    print len(msg) # result -> 32

有任何想法嗎?

如果診斷為未沖洗流是正確的,則以下為解決方法:

    try (OutputStream outputStream = socket.getOutputStream()) {
        message.writeDelimitedTo(outputStream);     
        System.out.println("Sending finished.");
    } catch (IOException e) {
        // SEE NOTES!!
        System.err.println("blah blah" + e.toString());
        System.exit(0);
    }

說明:通過使用try-with-resources ,我們確保無論塊如何退出,資源總是在塊退出時關閉。 這有兩個好處:

  1. 它確保流被沖洗
  2. 它確保您不會泄漏資源(即關聯的FileDescriptor )。 資源泄漏會導致各種不相關的I / O活動失敗……稍后……如果GC沒有機會先清理混亂。

筆記:

  1. 在代碼的深處調用System.exit(...)是一個壞主意。 它優先於其他可能的恢復方法,並使您的代碼難以擴展和/或重用。

  2. 如果捕獲並報告異常,則還應該在某處報告stacktrace...。

  3. 更好的策略是將IOException聲明為由封裝方法拋出,並在更高級別捕獲/報告/恢復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM