2013-08-23 25 views
1

我正在编写一个程序,该程序将与运行Java的另一台计算机进行交互,并且需要通过网络发送字符数组。在接收端,Java程序使用DataInputStream的readChar()函数并期望字符。但是,由于字符在C中存储为1个字节,所以在写入网络时遇到了一些麻烦。将C字符转换为UTF-16以通过网络传输

我该如何去转换呢?

实际协议规范是像这样:

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中接收端,和短不会正确地发送正确的长度,但字符数组不会。

在此先感谢!

+0

将转换您的文字吗?我知道C到Java的数据交换可能是一个真正的痛苦:) :) – JScoobyCed

+0

使用'byte'数组而不是'char'。 –

回答

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; 
} 

因为我需要的是能够跨越管道发送空终结,我转换#空字符,从而为base64促进转化是strlen的可以返回准确的长度

1

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

数据的连线格式是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);