我使用此代码从C客户端的Java服务器接收String。
if( recv( to_server_socket, &reply, sizeof( reply ), MSG_WAITALL ) != sizeof( reply ) )
{
printf( "socket read failed");
exit( -1 );
}
printf( "got reply: %d\n", ntohl( reply ) );
char buf[512];
ssize_t nbytes=0;
int byte_count;
byte_count = recv(to_server_socket, buf, sizeof buf, 0);
printf("recv()'d %d bytes of data in buf\n", byte_count);
buf[byte_count] = '\0';
printf("String : %s\n",buf);
例如,当Java服务器发送此String
时bZzrEcyVEmjmIf
我得到了这个结果
recv()'用buf字符串中的16字节数据:
所以我收到了16个字节,但是
printf("String : %s",buf);
不要给我任何东西。
服务器发送了此字符串
TYvuDbbKALp3scp
我试过这段代码
int i=0;
while(i<byte_count){
printf("String : %c\n",buf[i]);
i++; recv()'d 17 bytes of data in buf
结果我有
String:String:String:String:T String:Y String:v String :u String:D String:b String:b String:K String:A String:L String:p String:3 String:s String:c String:p
答案 0 :(得分:3)
似乎Java正在发送一个长度为前缀的字符串。前两个字节对应于长度字段。这两个字节决定了后面的字节数。这是我如何序列化和打印:
unsigned int str_len = buf[0] * 256 + buf[1];
char *str = buf + 2;
/* printf("%.*s\n", str_len, str); // You could use this,
instead of the following two lines: */
fwrite(str, 1, str_len, stdout);
putchar('\n');
值为0
的字节表示字符串的结尾,在C中。这解释了为什么buf
指向的字符串似乎为空。它还解释了为什么在长度为前缀的字符串中具有值0
的任何嵌入字符都会导致代码中注释掉的printf
停止打印字符串。
这是一个没有明确定义的视觉表示的字符值。这解释了为什么长度为前缀的字符串中的嵌入字符会导致fwrite
打印看起来很难看的字符。
答案 1 :(得分:2)
你确定你的角色是可打印的吗?
使用类似的内容查看您收到的内容:
for (int i = 0; i < byte_count; i++)
{
printf("%02x ", (unsigned int) buf[i]);
}
printf("\n"); // flush stdout
答案 2 :(得分:0)
发送的字符串包含14个字符。如果C应用程序收到16个字节,则有2个额外字节。可能它们被放置在缓冲区的开头并记下发送字符串的长度(这是我在TCP套接字上发送字符串的方式,因为不保证在那里保留消息边界)。如果第一个字节为零,你肯定什么都看不见。
尝试从buf
打印出所有16个字节的值。
我还建议在实际字符之前发送和解析字符串的长度,然后从socked中读取相应的(已知的)字节数,否则你可能会得到一个不完整的字符串或两个串联的字符串。
答案 3 :(得分:0)
stdout流被缓冲,你的printf应该包含\n
来刷新流
printf("String : %s\n",buf);
或
fflush(stdout);
答案 4 :(得分:0)
struct _received_data
{
unsigned char len_byte1;
unsigned char len_byte2;
char *str;
} received_data;
然后,一旦你收到缓冲区:
received_data *new_buf = (received_data*) buf;
printf( "String = %s", new_buf->str);
请注意发送和使用的缓冲区。 recv意味着携带二进制数据。如果传输的数据是字符串,则需要对其进行管理(即添加'\ 0'和缓冲区结束等)。此外,在这种情况下,您的Java服务器会在协议(客户端需要注意)之后添加长度字节。