0

我正在进行这种转换是因为从网络接收到的数据是unsigned char[8]数组。每两个字节代表一个 UINT16 数字。我想通过套接字发送这些字节,但是套接字需要对字符进行签名(我正在使用 little-endian)。

由于不可能将无符号字符转换为有符号字符,我想我可以从两个无符号字符形成一个 UINT16 数字,然后将该数字分解为两个有符号字符。

我的代码在 UINT16 数字介于 [0,127] 和 [256,65535] 之间的情况下工作,但是当值在 [128,255] 之间时,第一个字符会爆炸到 ~4294967295 并且 UINT16 现在表示为 ~65535。任何解释/解决方案?

uint16_t in = 129;
cout << "input is\t" << in << endl;

char lo = in & 0xFF;
char hi = in >> 8;

printf("%u", lo);
cout << "\n" << endl;
printf("%u", hi);
cout << "\n" << endl;

uint16_t out = lo | uint16_t(hi) << 8;

cout << "out is\t" << out << endl;

char[]通过套接字发送无符号时出现的错误;send()如果我使用以下初始化,我可以通过套接字(winsock)将它用作函数的适当参数。工作得很好。

char buffer[8]
for (int i= 0; i <8; i++){
 buffer[i] = 0x016; //random data
  }
send(clientSocket, buffer, 8, 0);

但是,如果按以下方式初始化缓冲区,则会出现错误:

unsigned char buffer[8]
for (int i=0; i < 8;i++){
 buffer[i] = 0x016; //again random data
 }
 send(clientSocket, buffer,8,0);

错误说明:

int send (SOCKET, const char *, int, int)': 无法将参数 2 从 unsigned char[8] 转换为 const char *

4

1 回答 1

3

[这是 C 的答案。OP 尚未阐明他们对 C 与 C++ 答案的需求。]

要使用具有类型参数的函数传递一个unsigned char命名的数组,只需将该数组转换为所需的类型,如下所示:buffersendconst char *

send(socket, (const char *) buffer, length, flags);

在 C 中,字符类型用于处理数据的“原始字节”(以及用于对字符进行编码,这是含义和用途的不幸合并),因此您可以通过这种方式发送任何类型的数据。套接字例程不会根据任何特定类型解释数据;他们将只传输位而不考虑任何符号。您可以使用相同的强制转换而不const接收数据,只要将数据写入其最初来自的相同类型的对象。

(可能存在发送和接收系统对各种事物使用不同表示的问题,例如在一个上使用大端存储,在另一个上使用小端存储,或者在一个上使用四个字节,在long另一个上使用八个字节,或者使用不同的填充和对齐方式在结构中。这些是与通过套接字传输原始数据无关的单独问题。)

正如 Kaz 所指出的,现代 API 通常将此类参数声明为void *or const void *,并且在将其他对象指针传递给它们时不需要强制转换。如果您遇到一些关于此的编译器警告消息,您可能正在使用过时的 API。)

于 2020-08-26T17:59:05.600 回答