我正在编写一个客户端/服务器应用程序,其中客户端是用C ++编写的,服务器是Java。它们之间的通信是由UDP协议进行的。 他们需要通过网络交换字符串消息。 现在,通信工作很多,客户端发送消息,服务器接收它,但我注意到Java端接收到的字符串就像是中继的。我的意思是,如果我尝试将其显示在控制台上,使用以下功能:
System.out.println("This is the message received "
+ message + " by the client just now");
我获得的结果是:
This is the message received *message*
使用字符串“由客户端刚刚”中断。
我认为这是由于Java和C ++之间存在一些不兼容性,但我找不到解决方案。
编辑: 这是接收者的代码:
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();
}
和发件人:
if(sendto(_socket, buffer, BUFFER_LEN, 0, (struct sockaddr*) &_serverAddress, addressLenght) == -1)
cout << "Trasmission failed!\n" << endl;
其中 buffer 是一个char数组。
答案 0 :(得分:3)
if(sendto(_socket, buffer, BUFFER_LEN, 0, (struct sockaddr*) &_serverAddress, addressLenght) == -1)
这一行似乎表明缓冲区是一个c字符串。如果是这种情况,则需要解析服务器端的额外NULL字符。来自c-string的NULL字符可能导致JAVA代码在看到NULL字符时立即停止处理字符串 - 这应该是它应该做的。
您可能只需修剪JAVA代码中字符串的最后一个字符。请记住,C字符串最后总是有一个额外的字符 - 一个NULL字符。
另外,BUFFER_LEN是一个宏吗?它的定义是什么?尝试发送实际的缓冲区长度,而不是预定义的长度。
即。
std::string buffer = "Your Message";
if(sendto(_socket, buffer.c_str(), buffer.length(), ...)
一般来说,在C ++中,什么时候都可以使用std :: string,而不是char *。
答案 1 :(得分:2)
一种可能性是您并不总是在缓冲区中接收预期的[长度]。因此,当您转换为字符串时,缓冲区末尾会有随机字节。这些字节中的一些可能代表控制代码与控制台输出相混淆。
我认为 String.trim将从String中删除NULL(\ 0)字符,但是,它不会删除值超过'\ u0020'的字符。 (参见javadoc:http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#trim())
如果正确,那么您需要检查字符串转换并且:
答案 2 :(得分:1)
您应该尝试在消息开头添加“消息”的实际大小
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;
然后在Java端,您读取前4个字节(假设在两个系统上sizeof int为4),然后使用您已读取的数字创建字符串。