【问题标题】:Converting uint32_t to network byte order将 uint32_t 转换为网络字节顺序
【发布时间】:2012-01-22 12:23:05
【问题描述】:

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

首先:我有一个可以工作的 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 描述符 (func),即 funcLength
+ param1 (strLength) 的长度为 4 字节
+ param1 (str) 的值的长度,即 strLength
+ param2 的长度为 4 字节
+ param2 (anz) 的值长度为 4 字节
+ NULL 字节 (\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 会给我以下输出:

packageLength875901497

那么现在有谁是我的问题所在吗?如有必要,我可以为您提供更多代码,但我认为错误是数据类型(uint32_t)或转换。

已获得帮助。提前致谢。

干杯 丹尼尔

【问题讨论】:

    标签: c networking client-server endianness uint32-t


    【解决方案1】:
    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 表示形式发送它们(即您将数字作为文本发送!)

    【讨论】:

    • 这是我做的一些试验和错误。但是我再次更改它,我得到了这样的 uint32_t packageLength, funcLength, strLength; funcLength = sizeof(func); strLength = strlen(str); anz = htonl(anz); packageLength = 4 + 4 + funcLength + 4 + strLength + 4 + 4 + 1; /*packageLength = htonl(packageLength);*/ strLength = htonl(strLength); funcLength = htonl(funcLength); uint32_t 字节 = htonl(4); uint32_t 尾随 = htonl(1); char byteBuffer[packageLength]; packageLength = htonl(packageLength);
    • 在 Java 中我有一个 ByteBuffer 是我放数据的,它给了我方法 .putInt() .put() 把东西放在一个 bytebuffer 中然后发送 ByteBuffer。我不知道如何将我的数据打包成一个字符数组。
    • 尽管如此,我在服务器端使用更改的代码(见上文)相同的 packageLength: packageLength875901497 如何告诉 c 将我的数据以二进制形式写入套接字?
    • *(int *) (byteBuffer + offset) = some_int;
    • 还有类似 memcpy 的字符串
    猜你喜欢
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 2015-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多