客户端-服务器消息解释



我正在尝试使用我的程序在服务器和客户端计算机之间进行数据通信。我对TCP及其工作原理知之甚少,所以我真的需要一些帮助。

到目前为止,我自己的一个简单化协议的消息定义如下:

int _header_signature;
int _offset_a;
int _offset_b;
int _size_a;
int _size_b;
wchar_t stuff[_size_a];
wchar_t stuff2[_size_b];
int _footer_signature;

它被序列化到缓冲区中,并使用Winsock的send()方法进行发送。

我的目标是以某种方式解释此消息,并提取服务器机器上类似结构中的数据。这是客户端和服务器之间的一对一连接。

我将如何在服务器部分解释这些数据?

我会:

a) 循环调用recv(),将我接收到的内容写入缓冲区,并仅当recv()没有更多要返回的内容并且发送的所有消息现在都在缓冲区时才开始解释消息?我也不确定如果客户端继续发送消息会发生什么。第二条消息(比如说)只有在第一条消息完成recv()'d时才会到达吗?或者,只要客户端继续发送消息,recv()就会继续返回内容吗?

b) 即使只有消息的一部分到达,也要在消息到达后立即开始解释?标题应该告诉我应该期待多少。(这似乎是一项漫长而乏味的任务)

难道没有一种方法可以像接收到的整个消息一样进入缓冲区,并以某种方式将其转换为结构,以便我可以处理数据吗?

如果我混淆了任何人,我很抱歉,如果有什么不清楚的地方,请告诉我,我会更新问题

您有很多问题捆绑在一起。

我认为最重要的一点是,当你在TCP套接字上调用receive时,它不会神奇地为你接收整个消息。事实上,如果你仔细想想,唯一可以保证的是你将在8位边界上接收数据。对receive的调用将被阻塞,直到至少有一个字节可用(可能更多),如果套接字关闭,它可能会返回一个空缓冲区。

有了这些知识,你应该在回答第2个问题的路上:"你是等到收到完整的信息,还是一直打接收电话",答案是你应该背靠背打接收电话。并解析输入缓冲区,因为它们将单个字节反序列化为应用程序协议规定的数据结构。

需要意识到的一件重要的事情是,拥有一个非常大的读取缓冲区并不能保证您在一次调用中获得整个消息!理解这一点非常重要。这意味着您的代码必须在这样的假设下运行,即您一次只能接收到1个字节,而接收到的数据与读取缓冲区的大小一样多。因此,当您决定读取缓冲区的大小时,您应该根据网络的MTU选择一个合理的值(大约1500字节通常是一个不错的选择)。每次调用recv()都会告诉您实际读取了多少字节。

一旦您开始接收数据,请将数据复制到一个临时缓冲区中,当您有足够的时间解析一条消息的标头时,对其进行解码,并确定您是否已经接收到整个消息,或者还有更多待处理的消息。当您收到整个消息后,将其进一步传递给您的应用程序。所有这些都应该在一定程度上独立于应用程序运行(接收代码应该能够尽可能快地接受数据,缓冲数据,解析数据,然后将解码的消息提供给应用程序)。

最新更新