java - Java 中的 TCP 客户端和 C 中的服务器

标签 java c tcp client-server

我想做一个聊天应用程序。客户端将用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(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);

我可以在C中读取s_packet并分离,但是我如何在java中做到这一点?

我怎样才能像Java中那样分开:

printf("\x1b[3%dm <%s>: %s \x1b[0m\n", se_packet.text_color, se_packet.alias, se_packet.text);

最佳答案

明确的答案是,这不会那么容易。您应该了解的第一件事是 tcp 的工作原理。 这是一种面向流的协议(protocol),tcp 中没有“消息”之类的东西。您只需发送和接收字节流。

在您的代码片段中,recv 可以在读取从服务器发送的部分消息后完成。相反,您应该在 java 中保留一个本地缓冲区并删除迄今为止收到的所有数据。在 while 循环中,您可以检测是否收到准备处理的消息。如果您的消息不是很大(小于 MTU ),那么您可能会很幸运并且始终收到整个“消息”。如果您不关心这一点,那么您可以只使用 java.io.InputStream.read(byte[]) 方法。

另一件需要考虑的事情是您如何解释收到的消息。 好吧,你别无选择,只能在 Java 中将其处理为 byte[]。 首先,你可能需要读取 s_packet.text_color。它可能会作为消息的前 4 个字节放置。您可以从这些字节构造 int (例如,请参见 Convert 4 bytes to int)。 但这不是一个好的做法。这是因为您发送的二进制数据取决于您的s_packet represented in memory 。在现实生活中,您通常不知道 int 或 char 的大小是多少,它取决于平台。或者有时 int 本身内部的字节顺序可能不同。相反,您应该声明自己的序列化协议(protocol)以及如何将消息转换为二进制数据,反之亦然。 希望对您有所帮助。

关于java - Java 中的 TCP 客户端和 C 中的服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40792071/

相关文章:

Java应用程序即使 "CLOSE ON EXIT"也无法关闭,TCP服务器

java - 如何创建具有数据库 CRUD 功能的服务任务

java - GWT 下载到客户端网站的 session 数据是否存在黑客拦截的风险?

java - FileOutputStream 中的 write 方法如何截断 int 类型参数

java - 使用 Jackson 将 JSON 字符串或对象反序列化为 String 字段

c - fgets、sscanf 和写入数组

c - 如何在 openGL 中加载 png 图像并使用鼠标移动它?

c - 如何在 C 中的 write_fds 和 select() 中正确设置标志

c - 如何验证tcp校验和

c++ - 如果 send() 返回 x 个字节,recv() 是否在一次调用中获得相同数量的字节?