我正在编写一个程序,它将与另一台运行Java的机器连接,我需要通过网络发送字符数组。在接收端,Java程序使用DataInputStream的readChar()函数并期望字符。但是,由于字符在C中存储为1个字节,因此在写入网络时遇到了一些问题。
我该如何转换呢?
实际的协议规范如下:
short: Contains length of char array
char 1, 2, 3...: The characters in the array
有关背景资料,我的简短转换是这样的:
char *GetBytesShort(short data)
{
short net_data = NET_htons(data);
char *ptr = (char *) malloc(sizeof(short));
memcpy(ptr, &net_data, sizeof(short));
return ptr;
}
我已经在Java的接收端测试了它,并且short以正确的长度正确发送,但字符数组没有。
提前致谢!
答案 0 :(得分:1)
有很多方法可以做到这一点。你想要做的是构建一个包含所有数据的缓冲区,然后将其传递到send(2)
系统调用以沿套接字发送它。
数据的有线格式是big-endian(也就是网络字节顺序),所以你应该确保先用最重要的字节存储你的值。我建议只需手动构建字节缓冲区以避免本地系统出现字节序问题(另请参阅The byte order fallacy),例如:
uint16_t dataLen = ...; // Length of data, in characters
uint16_t *charData = ...; // Character array
// Constructor packet data buffer to send. Error checking omitted for
// expository purposes.
size_t packetSize = 2 + dataLen * 2;
uint8_t *packet = malloc(packetSize);
// Copy length into buffer, big-endian
packet[0] = (uint8_t)(dataLen >> 8);
packet[1] = (uint8_t)(dataLen & 0xFF);
// Copy each character into the buffer, big-endian
for (uint16_t i = 0; i < dataLen; i++)
{
packet[2 + 2*i] = (uint8_t)(charData[i] >> 8);
packet[2 + 2*i + 1] = (uint8_t)(charData[i] & 0xFF);
}
// We're done -- send the packet
send(sockfd, packet, packetSize, 0);
答案 1 :(得分:0)
因为我只需要转换基本的ASCII字符(没有特殊字符),所以我只需要一个简单的解决方案来通过UTF16发送数据。
char *GetBytesString(char message[])
{
short str_len = strlen(message);
char *ptr = (char *) malloc(str_len * 2);
int i;
for (i = 0; i < str_len; i++)
{
int pos = i * 2;
if (message[i] == '#')
{
ptr[pos] = 0;
ptr[pos + 1] = 0;
}
else
{
ptr[pos] = 0;
ptr[pos + 1] = message[i];
}
}
return ptr;
}
因为我需要能够在管道上发送空终止符,所以我将#转换为空字符,以便strlen可以返回准确的长度