将uint32_t转换为网络字节顺序

时间:2012-01-22 12:23:06

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

我正在为我的学习做点什么,所以是的,它是家庭作业

首先:我有一个正常工作的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)或转换。

帮助是适当的。提前谢谢。

干杯 丹尼尔

1 个答案:

答案 0 :(得分:2)

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表示形式发送它们(即您将数字作为文本发送!)