简体   繁体   中英

Sending strings over the net from C++ client to Java server

I'm writing a client/server application in which, client is written in C++ and the server is Java. The communication between them is made by the UDP protocol. They need to exchange string messages over the net. Now, the communication works a lot, the client sends message and server receives it, but I noticed that the received string, on the Java side, is like trunked. I mean, if I try to display it onto the console, with the function:

System.out.println("This is the message received " 
                           + message + " by the client just now");

the result I obtain is:

This is the message received *message*

with the string "by the client just now" trunked out.

I think it's due to some incompatibility between Java and C++, but I can't found out the solution.

edit: here's the code of the receiver:

byte[] bytes = _packet.getData(); // Datagram Packet
hostName = getStringFromBytes(bytes, 0, 15);

(...)

private String getStringFromBytes (byte[] bytes, int lowerBound, int length) 
{
    byte[] bufferBytes  = new byte[length];
    System.arraycopy(bytes, lowerBound, bufferBytes, 0, length);

    return new String(bufferBytes).trim();
}

and the sender:

 if(sendto(_socket, buffer, BUFFER_LEN, 0, (struct sockaddr*) &_serverAddress, addressLenght) == -1)
    cout << "Trasmission failed!\n" << endl;

where buffer is an array of char.

if(sendto(_socket, buffer, BUFFER_LEN, 0, (struct sockaddr*) &_serverAddress, addressLenght) == -1)

This line seems to indicate that buffer is a c-string. If this is the case, you need to parse out the extra NULL character on your server end. The NULL character from the c-string is probably causing the JAVA code to stop processing the string as soon as it sees the NULL character--which is what it should do.

You could probably just trim the last character off of the string in your JAVA code. Remember that C-strings always have an extra character at the end--a NULL character.

Also, is BUFFER_LEN a macro? What is it defined as? Try just sending the actual buffer length, instead of a predefined length.

ie

std::string buffer = "Your Message";

if(sendto(_socket, buffer.c_str(), buffer.length(), ...)

And in general, in C++ , when at all possible use std::string, not char*.

One possibility is that you are not always receiving expected [length] in the buffer. As a result you have random bytes at the end of the buffer when you convert to string. It's possible some of those bytes represent a control code that messes with your console output.

I think String.trim will remove NULL (\\0) characters from a String, however, it will not remove characters with a value over '\ '. (See javadoc: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#trim () )

If correct, then you need to check your String conversion and either:

  • Detect the string end somehow independent of your expected byte buffer length. Perhaps by searching for 1st NULL terminator character. Or,
  • Replace\\remove all white-space characters in the String above and beyond what String.trim will do according to your expected string encoding.

You should try adding to the start of your message the actual size of your "message"

    std::string strMessage = "My Message";

    char* pBuffer = new char[sizeof(int) + strMessage.size()];

    int iSize = strMessage.size();
    memcpy(pBuffer, &iSize, sizeof(int));
    memcpy(pBuffer + sizeof(int), strMessage.c_str(), strMessage.size());


    if(sendto(_socket, pBuffer, sizeof(int) + iSize, 0, (struct sockaddr*) &_serverAddress, addressLenght) == -1)

...

delete pBuffer;

Then on the Java side, you read the first 4 bytes (assuming on both systems the sizeof int is 4) and then create the string with the number you have read.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM