1

我正在编写一个程序,它将与另一台运行 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;
}

我已经在 J​​ava 的接收端对其进行了测试,并且确实以正确的长度正确发送了 short ,但字符数组却没有。

提前致谢!

4

2 回答 2

1

有很多方法可以做到这一点。您要做的是构造一个包含所有数据的缓冲区,然后将其传递给send(2)系统调用以沿套接字发送。

数据的有线格式是大端(也称为网络字节顺序),因此您应该确保首先使用最重要的字节存储您的值。我建议仅手动构建字节缓冲区以避免本地系统出现字节顺序问题(另请参阅字节顺序谬误),例如:

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);
于 2013-08-23T05:19:56.423 回答
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 可以返回准确的长度

于 2013-08-29T07:47:15.740 回答