2013-11-22 36 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