我想做一个聊天应用程序。客户端将使用java编写,服务器将使用C编写。在服务器端,消息将作为struct发送。在客户端,如何使用Java读取和分离消息?
以下是一个示例数据包结构:
struct s_packet{
int text_color;
char text[TEXTSIZE];
char alias[ALIASIZE];
};
以下是一个示例服务器(在C中)发送功能:
send(iter->client.sockfd, (void *)se_packet, sizeof(s_packet), 0);
以下是C:
中的客户端recv函数示例recv(m_sockfd, (void *)&se_packet, sizeof(s_packet),0);
printf("\x1b[3%dm <%s>: %s \x1b[0m\n", se_packet.text_color, se_packet.alias, se_packet.text);
我可以读取s_packet并在C中分开,但我怎么能在java中做到?
我如何在Java中分开:
printf("\x1b[3%dm <%s>: %s \x1b[0m\n", se_packet.text_color, se_packet.alias, se_packet.text);
答案 0 :(得分:1)
明确的答案是,它不会那么容易。您应该了解的第一件事是tcp如何工作。 这是一个面向流的协议,在tcp中没有“消息”这样的东西。您只需发送和接收字节流。
在您的代码片段中recv
可以在阅读从服务器发送的部分消息后完成。相反,你应该在java中保留一个本地缓冲区并删除你目前收到的所有数据。在while循环中,您可以检测是否收到了可以处理的消息。如果您的消息不是很大(小于MTU),那么您可能会很幸运并且总是收到整个“消息”。如果您不关心这一点,那么您可以使用java.io.InputStream.read(byte[])
方法。
要考虑的另一件事是你如何解释收到的信息。 您没有其他选择,只能在Java中将其作为byte []进行处理。首先,您可能需要阅读s_packet.text_color
。它可能会被放置为消息中的前4个字节。您可以从thoes字节构造int(例如,参见Convert 4 bytes to int)。 但这不是一个好习惯。这是因为您发送的二进制数据取决于s_packet
represented in memory的方式。在现实生活中,你通常不知道int或char的大小是什么,它取决于平台。或者有时int内部的字节顺序可能不同。相反,您应该声明自己的序列化协议以及如何将消息转换为二进制数据,反之亦然。
希望它有所帮助。