繁体   English   中英

套接字编程:recv()

[英]Socket-programming: recv()

我有一个应用程序,其中各种实体通过套接字相互通信,我正在使用C编程语言。 当实体向另一个实体发送长消息时,recv()函数可能会部分地读取此消息。 因此,我必须通过附加所有收到的部分在接收方重新构建消息。

我的问题是与recv()相关的一般套接字编程问题。 recv()如何知道消息何时被完全读取? 我应该使用“\\ n”这样的特殊字符终止消息吗? 或者我应该将邮件的大小作为标题发送? 常见的做法是什么?

正如您所注意到的,使用流套接字时,没有内置的消息边界概念。 您需要构建一些方法来确定应用程序级协议中的消息结束。

您建议的两个选项都很常见:长度前缀(以消息长度开始每条消息)或消息结束分隔符(例如,可能只是基于文本的协议中的换行符,例如)。 第三种较少使用的选项是为每条消息强制使用固定大小。 这些选项的组合也是可能的 - 例如,包括长度值的固定大小的标题。

使用send()和recv()时,指定缓冲区大小。

如果您使用这种方式发送消息:

send(new_socket,message,strlen(message),0);

第三个参数是缓冲区的大小。

了解是否已成功发送数据包的一种方法是使用TCP套接字, send()recv()将返回相同的值。 您可以通过检查邮件大小是否与send()返回的值相同来在发件人端进行检查。

要在接收方检查,最简单的方法是在字符串中添加字符串分隔符\\0的结尾。

一旦开始在C中进行大量的网络编程,就会很快意识到为什么更高级别的语言很受欢迎! 基本上他们内置了大量的功能,你很快就会发现自己希望C能提供更多功能!

首先,我强烈建议您查看ZeroMQ( http://zeromq.org/bindings:c )及其C绑定。 在处理连接,消息划分等方面,这为你做了大量可怕的驴工作。此外,它在运行时很快; 它可以快速开发并快速运行,这是一个优秀图书馆的标志。

ZeroMQ即将成为完美的套接字库。 唯一没有做的事情(AFAIK)是主动监控连接,看它是否崩溃 - 你只是发现你是否尝试发送一些东西。 如果要检查连接的健康状况,则必须定期发送自己的连接测试消息。

其次,我鼓励你考虑序列化。 一旦你开始拥有指向分配内存的复杂数据结构,你就会开始进入复杂而困难的领域。 当遇到这个问题时,我选择使用ASN.1来使用Objective Systems( http://www.obj-sys.com/index.php )中的库和工具来定义和序列化我的数据结构。 它需要花钱,需要一些习惯,但我发现在开发中节省的时间非常值得。

除了序列化例程,它们还为您提供了一些C不提供的非常方便的附加功能。 例如,他们的代码生成器将为您提供复制数据类型的例程,如果该数据类型是一个充满引用已分配内存的指针的结构,则非常方便。

那里可能还有一些免费的工具和库。 一个很好的选择是Google的协议缓冲区,它具有C绑定( http://code.google.com/p/protobuf-c/ )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM