0

So I want to have a TCP connection between a Java client and a C++ server. Think of the client as an input device and the C++ server should receive JSON objects, parse them and use them in a game. It seems like the connection is established successfully, but 1) there is an error("parse error-unexpected ''") when I try to parse the json objects (i'm using nlohmann's json) and 2) when I don't even call doStuff a.k.a just print out the buffer, only weird characters are printed (e.g.).

I assume I messed up something in the sending/receiving of data(This is the first time I use C++), but I've lost two days and really can't figure it out!

In the Java client I have:

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());
    }
}

And in the C++ server:

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;
    }
}
Joana
  • 23
  • 3
  • If there is a parse error exception, then maybe your data contains some unexpected characters. Can you dump the content of `buf` and validate that it is proper JSON? – Niels Lohmann Oct 08 '17 at 11:14

2 Answers2

0

Since your char "buffer" is showing weird characters after recv() on the C++ server it seems to me the issue should be due to character encoding mismatch between the Java client and the C++ server. To verify you can check the "numbytes" returned by recv() on C++ server, it should be greater than the number of characters in the JSON string on the Java client.

Amit Rastogi
  • 926
  • 2
  • 12
  • 22
0

You are sending the lower 8 bytes of the JSON length but you're never doing anything about it at the receiver. This is almost certainly a mistake anyway. You shouldn't need to send the length. JSON is self-describing.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • What do you mean by self-describing? The server only knows that it's receiving chars, these are later parsed as json. – Joana Aug 15 '17 at 21:52
  • They should be parsed *now* as JSON. 'Self-describing' is, err, self-describing. But if you need the length word, you need it all, not just the lower 8 bits, and you need to *use* it at the other end, not just complain that binary prints out as binary. – user207421 Aug 15 '17 at 22:22