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

时间:2012-02-20 16:41:01

标签: java c++ string network-programming udp

我正在编写一个客户端/服务器应用程序,其中客户端是用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数组。

3 个答案:

答案 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())

如果正确,那么您需要检查字符串转换并且:

  • 以某种方式检测字符串结尾,与预期的字节缓冲区长度无关。也许通过搜索1st NULL终结符字符。或者,
  • 替换\删除字符串中的所有空白字符,超出String.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),然后使用您已读取的数字创建字符串。