通过 TCP 将 Java int 发送到 C
Sending Java int to C over TCP
我正在尝试通过 TCP 将 Java 的有符号整数发送到 C 客户端。
在 Java 端,我将整数写入输出流,如下所示:
static ByteBuffer wrapped = ByteBuffer.allocateDirect(4); // big-endian by default
public static void putInt(OutputStream out, int nr) throws IOException {
wrapped.rewind();
wrapped.putInt(nr);
wrapped.rewind();
for (int i = 0; i < 4; i++)
out.write(wrapped.get());
}
在C端,我是这样读取整数的:
int cnt = 0;
char buf[1];
char sizebuf[4];
while(cnt < 4) {
iResult = recv(ConnectSocket, buf, 1, 0);
if (iResult <= 0) continue;
sizebuf[cnt] = buf[0];
cnt++;
}
但是,如何在 C 中将 char 数组转换为整数?
编辑
我尝试了以下方法(以及相反的方法):
int charsToInt(char* array) {
return (array[3] << 24) | (array[2] << 16) | (array[1] << 8) | array[0];
}
再次编辑,因为我忘记了标签。
数据
例如当前发生的事情:
我收到:
char 0
char 0
char 12
char -64
the int becomes 2448
并使用从 char 数组创建 int 的函数:
int charsToInt(char* array) {
return ntohl(*((int*) array));
}
我希望有符号整数:3264
更新
睡一觉再调查..
更新
我有一个 Java 客户端可以正确解释整数并接收完全相同的字节:
0
0
12
-64
这取决于字节序,但您想要:
int x = sizebuf[0] +
(sizebuf[1] << 8) +
(sizebuf[2] << 16) +
(sizebuf[3] << 24);
或:
int x = sizebuf[3] +
(sizebuf[2] << 8) +
(sizebuf[1] << 16) +
(sizebuf[0] << 24);
请注意 sizebuf
需要有一个无符号类型才能正常工作。否则你需要屏蔽掉任何你不想要的符号扩展值:
int x = (sizebuf[3] & 0x000000ff) +
((sizebuf[2] << 8) & 0x0000ff00) +
((sizebuf[1] << 16) & 0x00ff0000) +
((sizebuf[0] << 24) & 0xff000000);
要转换 char 数组,一种可能是将其转换为 int* 并存储结果:
int result = *((int*) sizebuf)
这是有效的一行。另一种可能性是从字符计算整数。
for (i = 0 ; i < 4; i++)
result = result << sizeof(char) + buf[0]
选择你喜欢的那个。
亚历克西斯。
编辑:
sizeof(char) 是 1 因为 sizeof return 是一个 Byte 结果。所以正确的行是:
结果 = 结果 << (sizeof(char) * 8) + buf[0]
经典的 C 库已经有了你想要的方法,它独立于机器字节顺序:ntohl
!
// buf is a char */uint8_t *
uint32_t from_network = *((uint32_t *) buf);
uint32_t ret = ntohl(from_network);
这和 htonl
反向等期望 "network order" 是大端。
(上面的代码假定buf
至少有4个字节;ntohl
和htonl
的return类型和参数类型是uint32_t
;JLS 将 int
定义为 4 个字节,因此可以保证结果)
我正在尝试通过 TCP 将 Java 的有符号整数发送到 C 客户端。
在 Java 端,我将整数写入输出流,如下所示:
static ByteBuffer wrapped = ByteBuffer.allocateDirect(4); // big-endian by default
public static void putInt(OutputStream out, int nr) throws IOException {
wrapped.rewind();
wrapped.putInt(nr);
wrapped.rewind();
for (int i = 0; i < 4; i++)
out.write(wrapped.get());
}
在C端,我是这样读取整数的:
int cnt = 0;
char buf[1];
char sizebuf[4];
while(cnt < 4) {
iResult = recv(ConnectSocket, buf, 1, 0);
if (iResult <= 0) continue;
sizebuf[cnt] = buf[0];
cnt++;
}
但是,如何在 C 中将 char 数组转换为整数?
编辑
我尝试了以下方法(以及相反的方法):
int charsToInt(char* array) {
return (array[3] << 24) | (array[2] << 16) | (array[1] << 8) | array[0];
}
再次编辑,因为我忘记了标签。
数据
例如当前发生的事情:
我收到:
char 0
char 0
char 12
char -64
the int becomes 2448
并使用从 char 数组创建 int 的函数:
int charsToInt(char* array) {
return ntohl(*((int*) array));
}
我希望有符号整数:3264
更新 睡一觉再调查..
更新 我有一个 Java 客户端可以正确解释整数并接收完全相同的字节:
0
0
12
-64
这取决于字节序,但您想要:
int x = sizebuf[0] +
(sizebuf[1] << 8) +
(sizebuf[2] << 16) +
(sizebuf[3] << 24);
或:
int x = sizebuf[3] +
(sizebuf[2] << 8) +
(sizebuf[1] << 16) +
(sizebuf[0] << 24);
请注意 sizebuf
需要有一个无符号类型才能正常工作。否则你需要屏蔽掉任何你不想要的符号扩展值:
int x = (sizebuf[3] & 0x000000ff) +
((sizebuf[2] << 8) & 0x0000ff00) +
((sizebuf[1] << 16) & 0x00ff0000) +
((sizebuf[0] << 24) & 0xff000000);
要转换 char 数组,一种可能是将其转换为 int* 并存储结果:
int result = *((int*) sizebuf)
这是有效的一行。另一种可能性是从字符计算整数。
for (i = 0 ; i < 4; i++)
result = result << sizeof(char) + buf[0]
选择你喜欢的那个。
亚历克西斯。
编辑: sizeof(char) 是 1 因为 sizeof return 是一个 Byte 结果。所以正确的行是: 结果 = 结果 << (sizeof(char) * 8) + buf[0]
经典的 C 库已经有了你想要的方法,它独立于机器字节顺序:ntohl
!
// buf is a char */uint8_t *
uint32_t from_network = *((uint32_t *) buf);
uint32_t ret = ntohl(from_network);
这和 htonl
反向等期望 "network order" 是大端。
(上面的代码假定buf
至少有4个字节;ntohl
和htonl
的return类型和参数类型是uint32_t
;JLS 将 int
定义为 4 个字节,因此可以保证结果)