2013-08-23 26 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);