2013-11-22 31 views
1

我正在尋找幾個小時以獲得有關我的問題的答案,但沒有發現任何內容。也許我在這裏得到一些幫助。從Java客戶端接收數據(數據包含int,簡寫,字符串)

我在做什麼: Java客戶端發送消息到C-Server。該消息包含不同類型,如整數,短和字符串(例如message = int:total_msg_length; short:operation; string:hello - > total_msg-length = 4(整數大小),operation = 2 ,你好= 5(每個字母是1字節= 5)。

所以,我怎樣才能在我的服務器接收消息?下面的代碼接收一個Integer(工作正常)下一步將接收一個簡短的然後用一個字符串(在US-ASCII轉換)

int *msg; 
int recv_size; 
int final_msg; 

if((recv_size = recv(client_socket, &msg, sizeof(msg), 0)) < 0){ 
    error_exit("Fehler bei recv(message_len)"); 
} 

final_msg = endian_swap(msg); 
printf("Message: %d\n", final_msg); 

return final_msg; 

有林感謝每個幫助請原諒使用一個字節數組,而不是字符緩衝區的方式我的英語不好,我來自德國。?: - )

+0

注意:您傳遞的''代替的sizeof(int)的''的sizeof(MSG)。你的代碼工作原因是因爲在大多數平臺上兩種尺寸都是相同的,但這是不正確的。你想要接收一個int,而不是一個int指針。通常,指針的大小與指向值的大小不同。 – Claudix

+0

仔細閱讀'recv()'/'send()'的手冊頁,並瞭解到至少對於套接字來說,這兩個函數不一定會接收/發送儘可能多的字節,而是很少。因此,圍繞此類呼叫進行計數,直到收到/發送所有數據都是一個好主意,而不是說必不可少。 – alk

回答

2

您需要創建一個通用的「read_n_bytes」函數。

這可以用於在三次連續調用中讀取消息大小,操作和文本。

然後,您將這三個調用包裝在函數中以調用以讀取整個消息。


一個普通的讀者可能是這樣的:

/* 
* Reads n bytes from sd into where p points to. 
* 
* returns 0 on succes or -1 on error. 
* 
* Note: 
* The function's name is inspired by and dedicated to "W. Richard Stevens" (RIP). 
*/ 
int readn(int sd, void * p, size_t n) 
{ 
    size_t bytes_to_read = n; 
    size_t bytes_read = 0; 

    while (bytes_to_read > bytes_read) 
    { 
    ssize_t result = read(sd, p + bytes_read, bytes_to_read); 
    if (-1 == result) 
    { 
     if ((EAGAIN == errno) || (EWOULDBLOCK == errno)) 
     { 
     continue; 
     } 

#  ifdef DEBUG  
     { 
     int errno_save = errno; 
     perror("read() failed"); 
     errno = errno_save; 
     } 
#  endif 

     break; 
    } 
    else if(0 == result) 
    { 
#  ifdef DEBUG 
     {  
     int errno_save = errno; 
     fprintf(stderr, "%s: Connection closed by peer.", __FUNCTION__); 
     errno = errno_save; 
     } 
#  endif 

     break; 
    } 

    bytes_to_read -= result; 
    bytes_read += result; 
    } 

    return (bytes_read < bytes_to_read) ?-1 :0; 
} 
+0

你的函數應該接收消息的大小來讀取參數,所以我猜,在調用這個函數之前,我們需要從發送者那裏接收消息的大小? – UrbiJr

+1

@UrbiJr:正確。要麼你知道要傳入的字節數,要麼只調用'readn()'兩次,一次接收''的一個明確定義大小的* binary *整數,比方說'uint16_t',然後將這個值用於另一個調用'readn()'來接收一個正確長度的塊(或一個錯誤)。 – alk

+0

如果你能幫助它將不勝感激。我真的被卡住了.. – UrbiJr