简体   繁体   English

通过网络从C ++客户端向Java服务器发送字符串

[英]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. 我正在编写一个客户端/服务器应用程序,其中,客户端是用C ++编写的,服务器是Java。 The communication between them is made by the UDP protocol. 它们之间的通信是通过UDP协议进行的。 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. 现在,通信非常有效,客户端发送消息,服务器接收消息,但是我注意到,在Java端,接收到的字符串就像是中继的。 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. 我认为这是由于Java和C ++之间的某些不兼容,但我找不到解决方案。

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. 其中buffer是char数组。

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

This line seems to indicate that buffer is a c-string. 这行似乎表明缓冲区是一个c字符串。 If this is the case, you need to parse out the extra NULL character on your server end. 在这种情况下,您需要在服务器端解析额外的NULL字符。 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. C字符串中的NULL字符可能会导致JAVA代码一看到NULL字符就立即停止处理该字符串,这是应该做的。

You could probably just trim the last character off of the string in your JAVA code. 您可能只需要修剪JAVA代码中字符串的最后一个字符即可。 Remember that C-strings always have an extra character at the end--a NULL character. 请记住,C字符串始终在末尾有一个额外的字符-空字符。

Also, is BUFFER_LEN a macro? 另外,BUFFER_LEN是宏吗? 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*. 通常,在C ++中,尽可能使用std :: string,而不是char *。

One possibility is that you are not always receiving expected [length] in the buffer. 一种可能是您并不总是在缓冲区中收到预期的[length]。 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 '\ '. 认为 String.trim将从字符串中删除NULL(\\ 0)字符,但是,它不会删除值超过'\\ u0020'的字符。 (See javadoc: http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#trim () ) (请参阅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. 也许通过搜索第一个NULL终止符。 Or, 要么,
  • Replace\\remove all white-space characters in the String above and beyond what String.trim will do according to your expected string encoding. 替换\\删除String中的所有空格字符,超出和超出String.trim根据您期望的字符串编码将执行的操作。

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. 然后在Java端,读取前4个字节(假设在两个系统上,sizeof int为4),然后使用读取的数字创建字符串。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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