C++ 对于客户端,了解服务器发送的包有多大的好处
我对网络编程非常陌生,所以我希望这不是一个完全的新手问题。C++ 对于客户端,了解服务器发送的包有多大的好处,c++,qt,networking,network-programming,C++,Qt,Networking,Network Programming,我对网络编程非常陌生,所以我希望这不是一个完全的新手问题。 我在Qt主页上阅读了一篇关于如何构建小型服务器的教程,我发现: QByteArray块; QDataStream out(块和QIODevice::WriteOnly); 这是标准的东西 对于接收程序来说,通过网络传输的所有内容都只是一个字节流。流除了应用程序强加给它的内容之外没有任何意义,正如文件除了应用程序如何定义其记录、行等之外没有任何意义一样。 客户机和服务器理解流的唯一方法是建立一个他们一致同意的约定或协议 因此,实现这一目标
我在Qt主页上阅读了一篇关于如何构建小型服务器的教程,我发现:
QByteArray块;
QDataStream out(块和QIODevice::WriteOnly);
这是标准的东西
对于接收程序来说,通过网络传输的所有内容都只是一个字节流。流除了应用程序强加给它的内容之外没有任何意义,正如文件除了应用程序如何定义其记录、行等之外没有任何意义一样。
客户机和服务器理解流的唯一方法是建立一个他们一致同意的约定或协议
因此,实现这一目标的一些常见方法是:
- 具有指定消息结尾的分隔符(例如回车符)
- 传递一个长度字段,如示例中所示,它告诉接收者下一条消息包含多少数据
- 只需建立一个固定的约定(例如,每条消息将是20个字节,或者“a”类记录将是一种定义的格式,而“B”类记录将是另一种格式…)
- 只需将其视为一个流,完全没有约定(例如,获取网络上的任何内容,并将其放入一个文件中,而不关注它是什么)
长度字节方法的一个优点是,接收器确切地知道需要多少数据。通过一些附加的健全性检查,这有助于消除应用程序中的缓冲区溢出等问题。这是标准的东西
对于接收程序来说,通过网络传输的所有内容都只是一个字节流。流除了应用程序强加给它的内容之外没有任何意义,正如文件除了应用程序如何定义其记录、行等之外没有任何意义一样。
客户机和服务器理解流的唯一方法是建立一个他们一致同意的约定或协议
因此,实现这一目标的一些常见方法是:
- 具有指定消息结尾的分隔符(例如回车符)
- 传递一个长度字段,如示例中所示,它告诉接收者下一条消息包含多少数据
- 只需建立一个固定的约定(例如,每条消息将是20个字节,或者“a”类记录将是一种定义的格式,而“B”类记录将是另一种格式…)
- 只需将其视为一个流,完全没有约定(例如,获取网络上的任何内容,并将其放入一个文件中,而不关注它是什么)
长度字节方法的一个优点是,接收器确切地知道需要多少数据。通过一些附加的健全性检查,这有助于消除应用程序中的缓冲区溢出等问题。在接收数据包之前了解数据包大小具有性能优势。
然后,您可以从堆或使用的任何缓冲区管理中准确分配所需的字节数,并接收对“网络接收函数”的逐点(理想情况下是一个)调用。
如果您不知道优势的大小,则必须调用“网络接收函数”来接收很小部分的消息
由于“网络接收函数”(可能是recv()或Qt提供给您的任何函数)是一个系统调用,它还进行TCP缓冲区处理等操作,因此应假定该函数速度较慢,每次调用的开销较大。因此,您应该尽可能少地调用它。在接收数据包之前知道数据包的大小具有性能优势。
然后,您可以从堆或使用的任何缓冲区管理中准确分配所需的字节数,并接收对“网络接收函数”的逐点(理想情况下是一个)调用。
如果您不知道优势的大小,则必须调用“网络接收函数”来接收很小部分的消息
由于“网络接收函数”(可能是recv()或Qt提供给您的任何函数)是一个系统调用,它还进行TCP缓冲区处理等操作,因此应假定该函数速度较慢,每次调用的开销较大。所以你应该尽可能少地说
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out << (quint16)0;
out << "..."; // just some text
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));