将 uint32_t 转换为网络字节顺序

发布于 2024-12-28 11:10:33 字数 2106 浏览 3 评论 0原文

我正在为我的学习做一些事情,所以是的,这是家庭作业

首先:我有一个可用的 Java 服务器应用程序,我还有一个用 c 编写的客户端应用程序,现在用 java 运行。 很简单,我无法将 uint32_t 发送到我的 java 服务器。

让我们展示一些代码:

char* callString(char func, char* str, uint32_t anz) {

  uint32_t packageLength, funcLength, strLength;
  funcLength = htonl(sizeof(func));
  strLength = htonl(strlen(str));
  uint32_t byte = htonl(4);
  uint32_t trailing = htonl(1);
  anz = htonl(anz);

  packageLength = byte + byte + funcLength + byte + strLength + byte + byte + trailing;
  /*packageLength = htonl(packageLength);*/

  char byteBuffer[ntohl(packageLength)];


  printf("%i\n", packageLength);
  printf("%i\n", htonl(packageLength));
  printf("%i\n", ntohl(packageLength));

  sprintf(byteBuffer, "%i%i%c%i%s%i%i%c", packageLength, byte, func, byte, str, byte, anz, '\0');

  printf("%s\n", byteBuffer);

  if(write(sock, byteBuffer, packageLength) < 0) {
    printf("write: Konnte keine Daten zum gegenüber senden.\n");
    exit(EXIT_FAILURE);
  }
  char* retVal = "hallo";
  return retVal;
}

很简单,我用 func = 'v'、str = "hallo" 和 anz = 2 来调用这个函数 这会给我一个 27 字节的 packageLength。

包的构建如下:
= packageLength (int) 为 4 字节
+ 函数描述符的长度 (funcLength) 为 4 字节
+ 函数描述符 (func) 即 funcLength
+ param1 的长度 (strLength) 为 4 字节
+ param1 (str) 值的长度,即 strLength
+ param2 的长度为 4 字节
+ param2 (anz) 值的长度,为 4 字节
+ NULL Byte (\0),即 1 个字节

我认为我所做的转换是错误的,也许我使用了错误的数据类型。在服务器端,我使用 Java ByteBuffer 来收集数据。首先,我从网络读取 4 字节的包长度,这将告诉我在获得整个数据包之前必须读取多长时间的信息:

byte[] msgLength = new byte[4];
try {
handle.getInputStream().read(msgLength);
} catch (IOException ex) {
    System.out.println("could not receive byte stream: msgLength");
    break;
}
ByteBuffer receive;

receive = ByteBuffer.wrap(msgLength);

int packageLength = receive.getInt();
System.out.println("packageLength" + packageLength);

最后一个 println 将给出以下输出:

包长度875901497

那么现在有人知道我的问题出在哪里吗?如果需要,我可以为您提供更多代码,但我认为错误要么是数据类型(uint32_t),要么是转换。

帮助是appriced。提前致谢。

干杯 丹尼尔

i'm doing stuff for my studies, so yeah, it's homework.

First: I got a working Java Server Application, i also had this client application i'm writing in c now working in java.
Simple as is, i fail at sending the uint32_t to my java server.

So let's show off some code:

char* callString(char func, char* str, uint32_t anz) {

  uint32_t packageLength, funcLength, strLength;
  funcLength = htonl(sizeof(func));
  strLength = htonl(strlen(str));
  uint32_t byte = htonl(4);
  uint32_t trailing = htonl(1);
  anz = htonl(anz);

  packageLength = byte + byte + funcLength + byte + strLength + byte + byte + trailing;
  /*packageLength = htonl(packageLength);*/

  char byteBuffer[ntohl(packageLength)];


  printf("%i\n", packageLength);
  printf("%i\n", htonl(packageLength));
  printf("%i\n", ntohl(packageLength));

  sprintf(byteBuffer, "%i%i%c%i%s%i%i%c", packageLength, byte, func, byte, str, byte, anz, '\0');

  printf("%s\n", byteBuffer);

  if(write(sock, byteBuffer, packageLength) < 0) {
    printf("write: Konnte keine Daten zum gegenüber senden.\n");
    exit(EXIT_FAILURE);
  }
  char* retVal = "hallo";
  return retVal;
}

Simple as is, i call this function with func = 'v', str = "hallo" and anz = 2
which will give me a packageLength of 27 bytes.

Package is build like this:
= packageLength (int) which is 4 byte
+ length of function descriptor (funcLength) which is 4 byte
+ func descriptor (func) which is funcLength
+ length of param1 (strLength) which is 4 byte
+ length of value of param1 (str) which is strLength
+ length of param2 which is 4 byte
+ length of value of param2 (anz) which is 4 byte
+ NULL Byte (\0) which is 1 byte

I assume the conversion i do is wrong maybe i'm using the wrong datatype. On server-side i use the Java ByteBuffer to collect the data. At first i read the 4 byte packagelength from the network which will give me the information of how long i have to read until i get the whole data package:

byte[] msgLength = new byte[4];
try {
handle.getInputStream().read(msgLength);
} catch (IOException ex) {
    System.out.println("could not receive byte stream: msgLength");
    break;
}
ByteBuffer receive;

receive = ByteBuffer.wrap(msgLength);

int packageLength = receive.getInt();
System.out.println("packageLength" + packageLength);

The last println will give me the following output:

packageLength875901497

So does anyone now where my problem is? I can provide you with more code if necessary but i think the error is either the datatype (uint32_t) or the conversion.

Help is appriciated. Thanks in advance.

Cheers
Daniel

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

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

发布评论

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

评论(1

故笙诉离歌 2025-01-04 11:10:33
funcLength = htonl(sizeof(func));
strLength = htonl(strlen(str));
uint32_t byte = htonl(4);
uint32_t trailing = htonl(1);
anz = htonl(anz);

packageLength = byte + byte + funcLength + byte + strLength + byte + byte + trailing;

您将尺寸转换为网络顺序,然后将它们加在一起以获得 packageLength。您应该在使用 htonl 将它们转换为网络顺序之前将它们添加在一起。

除此之外,所有这些:

sprintf(byteBuffer, "%i%i%c%i%s%i%i%c", packageLength, byte, func, byte, str, byte, anz, '\0');

都是错误的,因为我假设您想将它们作为二进制发送,但是使用上面的 sprintf 会以其基数 10 ASCII 表示形式发送它们(即您发送的数字作为文本!)

funcLength = htonl(sizeof(func));
strLength = htonl(strlen(str));
uint32_t byte = htonl(4);
uint32_t trailing = htonl(1);
anz = htonl(anz);

packageLength = byte + byte + funcLength + byte + strLength + byte + byte + trailing;

You're converting the sizes to network order and then adding them together for packageLength. You should add them together before converting them to network order with htonl.

Apart from that, all this:

sprintf(byteBuffer, "%i%i%c%i%s%i%i%c", packageLength, byte, func, byte, str, byte, anz, '\0');

is wrong, because I assume you want to send them as binary, but using sprintf as above would send them in their base 10 ASCII representation (i.e. you're sending the numbers as text!)

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