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

发布于 2025-01-07 12:47:34 字数 1122 浏览 1 评论 0原文

我正在编写一个客户端/服务器应用程序,其中客户端是用 C++ 编写的,服务器是 Java 编写的。它们之间的通信是通过UDP协议进行的。 他们需要通过网络交换字符串消息。 现在,通信工作正常,客户端发送消息,服务器接收消息,但我注意到在 Java 端接收到的字符串就像 trunked 一样。我的意思是,如果我尝试将其显示到控制台上,使用以下功能:

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

我获得的结果是:

This is the message received *message*

字符串“by the client just now”被删除。

我认为这是由于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 是一个字符数组。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冷月断魂刀 2025-01-14 12:47:34
if(sendto(_socket, buffer, BUFFER_LEN, 0, (struct sockaddr*) &_serverAddress, addressLenght) == -1)

这一行似乎表明 buffer 是一个 c 字符串。如果是这种情况,您需要在服务器端解析出多余的 NULL 字符。 c 字符串中的 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*。

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.

i.e.

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*.

酷炫老祖宗 2025-01-14 12:47:34

一种可能性是您并不总是在缓冲区中收到预期的[长度]。因此,当转换为字符串时,缓冲区末尾会出现随机字节。其中一些字节可能代表与控制台输出混淆的控制代码。

我认为 String.trim 将从字符串中删除 NULL (\0) 字符,但是,它不会删除值超过 '\u0020' 的字符。 (请参阅 javadoc:http://docs .oracle.com/javase/1.5.0/docs/api/java/lang/String.html#trim() )

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

  • 以某种方式检测字符串结尾与您预期的字节缓冲区长度无关。也许通过搜索第一个 NULL 终止符。或者,
  • 替换\删除字符串中高于 String.trim 将根据您预期的字符串编码执行的操作的所有空白字符。

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 '\u0020'. (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.
随心而道 2025-01-14 12:47:34

您应该尝试将“消息”的实际大小添加到消息的开头,

    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 个字节(假设在两个系统上,int 的 sizeof 都是 4),然后使用您的数字创建字符串已读过。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文