客户服务器消息解释

时间:2014-11-01 01:24:42

标签: c++ winsock network-protocols

我尝试使用我的程序在服务器和客户端计算机之间传递数据。我对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()时,第二条消息才能说出来吗?或者只要客户端不断发送消息,recv()会继续返回内容吗?

OR

b)即使只有一部分消息到达,他们一旦开始解释这些消息就开始工作了吗?标题应该告诉我还有多少。 (这似乎是一项非常漫长而乏味的任务)

是不是有办法让收到的整个消息进入缓冲区,并以某种方式将其转换为结构,以便我可以处理数据?

对不起,如果我混淆了任何人,如果有什么不清楚请告诉我,我会更新问题

1 个答案:

答案 0 :(得分:2)

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

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

有了这些知识,你应该在回答2号问题的路上:“你要等到收到整条信息还是继续拨打电话”,答案是你应该背靠背拨打电话。并解析输入缓冲区,因为它们将各个字节反序列化为应用程序协议所规定的数据结构。

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

一旦开始接收数据,将数据复制到临时缓冲区,当您有足够的数据解析一条消息的标题时,解码它并确定您是否收到了整条消息,或者还有更多未决消息。当您收到整条消息后,将其进一步传递给您的应用程序。所有这些应该在某种程度上独立于应用程序 (接收代码应该能够尽可能快地接受数据,缓冲它,解析它然后将解码的消息提供给应用程序)。