2017-08-15 62 views
0

所以我想在Java客戶端和C++服務器之間建立TCP連接。將客戶端視爲輸入設備,C++服務器應該接收JSON對象,解析它們並在遊戲中使用它們。 這似乎是連接建立成功,但1)當我嘗試解析json對象(我​​使用nlohmann's json)和2)當我沒有錯誤(「parse error-unexpected''」)即使調用doStuff,也就是打印緩衝區,只打印奇怪的字符(例如)。如何正確解析Java + C++ TCP連接中的JSON對象?

我假設我在發送/接收數據時弄錯了一些東西(這是我第一次使用C++),但是我已經失去了兩天,真的不知道它!

在Java客戶端,我有:

private void connect() { 
    try { 
     hostname = conn.getHostname(); 
     portnumber = conn.getPortNr(); 
     socket = new Socket(hostname, portnumber); 
     out = new OutputStreamWriter(socket.getOutputStream()); 
     in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     Log.e(debugString, e.getMessage()); 
    } 
} 

public void sendMessage(String json) { 
    try { 
     //connect(); 
     out.write(json.length()); 
     Log.d(debugString, String.valueOf(json.length())); 
     out.flush(); 
     out.write(json); 
     out.flush(); 
     Log.d(debugString, json); 

     in.read(); 
     this.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     Log.e(debugString, e.getMessage()); 
    } 
} 

和C++服務器:

void Server::startConnection() { 

    if (listen(s, 1) != 0) { 
     perror("Error on listen"); 
     exit(EXIT_FAILURE); 
    } 

    listen(s, 1); 

    clilen = sizeof(cli_addr); 

    newsockfd = accept(s, (struct sockaddr *) &cli_addr, &clilen); 
    if (newsockfd < 0) { 
     close(newsockfd); 
     perror("Server: ERROR on accept"); 
     exit(EXIT_FAILURE); 
    } 
    puts("Connection accepted"); 

    int numbytes; 
    char buffer[MAXDATASIZE]; 
    while (1) 
    { 
     numbytes = recv(s,buffer,MAXDATASIZE-1,0); 
     buffer[numbytes]='\0'; 
     //Here's where the weird stuff happens 
     //cout << buffer; 
     //doStuff(numbytes,buffer); 

     if (numbytes==0) 
     { 
      cout << "Connection closed"<< endl; 

      break; 
     } 
    } 
} 

bool Server::sendData(char *msg) { 

    int len = strlen(msg); 
    int bytes_sent = send(s,msg,len,0); 
    if (bytes_sent == 0) { 
     return false; 
    } else { 
     return true; 
    } 
} 

void Server::doStuff(int numbytes, char * buf) { 
    json jdata; 
    try { 
     jdata.clear(); 
     jdata = nlohmann::json::parse(buf); 
     if (jdata["type"] == "life") { 
     life = jdata["value"]; 
     puts("json parsed"); 
     } 

    } catch (const std::exception& e) { 
     cerr << "Unable to parse json: " << e.what() << std::endl; 
    } 
} 
+0

如果存在解析錯誤異常,那麼您的數據可能包含一些意外字符。你可以轉儲buf的內容並驗證它是正確的JSON嗎? –

回答

0

由於您的字符 「緩衝」 正顯示出奇怪的字符的recv(後)在C++服務器它在我看來,問題應該歸因於Java客戶端和C++服務器之間的字符編碼不匹配。要驗證您可以檢查C++服務器上recv()返回的「numbytes」,它應該大於Java客戶端上JSON字符串中的字符數。

0

您正在發送JSON長度的低8字節,但您從未在接收器上做過任何事情。無論如何,這幾乎肯定是一個錯誤。你不需要發送長度。 JSON是自我描述的。

+0

自我描述是什麼意思?服務器只知道它正在接收字符,這些後來被解析爲json。 – Joana

+0

他們應該被解析*現在*爲JSON。 「自我描述」就是自我描述。但是如果你需要長度單詞,你需要全部,而不僅僅是低8位,並且你需要在另一端使用它,而不只是抱怨二進制打印出二進制。 – EJP