2

我使用此代码在 C 客户端中从 Java 服务器接收字符串。

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()'d buf String 中的 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

结果我有

字符串:字符串:字符串:字符串:T 字符串:Y 字符串:v 字符串:u 字符串:D 字符串:b 字符串:b 字符串:K 字符串:A 字符串:L 字符串:p 字符串:3 字符串:s 字符串:c 字符串: p

4

5 回答 5

3

你确定你的字符是可打印的吗?

使用类似这样的东西来查看您收到的内容:

for (int i = 0; i < byte_count; i++)
{
    printf("%02x ", (unsigned int) buf[i]);    
}
printf("\n");  // flush stdout
于 2013-05-04T13:42:46.387 回答
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打印出看起来很尴尬的字符。

于 2013-05-04T14:18:48.490 回答
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);

请注意,在 send 和 recv 中使用的缓冲区是用来承载二进制数据的。如果传输的数据是字符串,则需要对其进行管理(即,添加 '\0' 和缓冲区结尾等)。此外,在这种情况下,您的 Java 服务器正在按照协议(客户端需要注意)添加长度字节。

于 2013-05-04T16:36:47.303 回答
0

正在发送的字符串包含 14 个字符。如果 C 应用程序接收到 16 个字节,则有 2 个额外字节。可能它们被放置在缓冲区的开头并注意正在发送的字符串的长度(这是我通过 TCP 套接字发送字符串的方式,因为不能保证将消息边界保留在那里)。如果第一个字节为零,您肯定什么也看不到。

尝试从buf.

我还建议在实际字符之前发送和解析一段字符串,然后从 socked 中读取适当的(已知)字节数,否则您可能会得到一个不完整的字符串或两个连接的字符串。

于 2013-05-04T13:38:34.500 回答
0

标准输出流被缓冲,你的 printf 应该包括\n刷新流

printf("String : %s\n",buf);

或者

fflush(stdout); 
于 2013-05-04T13:38:56.400 回答