【问题标题】:Socket-programming: recv()套接字编程:recv()
【发布时间】:2013-11-06 18:47:54
【问题描述】:

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

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

【问题讨论】:

    标签: c sockets


    【解决方案1】:

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

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

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

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

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

    为了在接收方进行检查,最简单的方法是将字符串结尾分隔符 \0 添加到您的字符串中。

    【讨论】:

    • 对于发送分隔符,strlen(message)+1 就可以了。
    • 除此之外,最好谈谈“发送方”。从连接一开始,双方就可以发送和接收,所以这里使用“服务器”这个词是非常具有误导性的。
    • @glglgl 谢谢我将服务器和客户端固定为发送者和接收者。另外我假设字符串已经有 \0 分隔符,因此它已经包含在字符串的长度中,但是如果字符串没有分隔符,那么你是对的。
    • send() 和 recv() 没有理由返回相同的值。 TCP 是字节流协议,而不是消息协议。如果你想要消息边界,你必须自己实现它们。例如,Recv() 完全有权一次返回一个字节。 -1
    【解决方案2】:

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

    首先,我强烈建议您查看 ZeroMQ (http://zeromq.org/bindings:c) 及其 C 绑定。在处理连接、消息分界等方面,这为你做了很多可怕的工作。另外,它在运行时很快;快速开发和快速运行,这是一个好的库的标志。

    ZeroMQ 已接近完美的套接字库。它唯一还没有做的事情(AFAIK)是主动监视连接以查看它是否已折叠 - 您只会发现您是否尝试发送某些内容。如果您想检查连接的健康状况,您必须定期发送自己的连接测试消息。

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

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

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 谢谢...了解常见做法真的很有帮助。
      猜你喜欢
      • 1970-01-01
      • 2013-06-09
      • 1970-01-01
      • 2015-08-19
      • 2014-08-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-11
      相关资源
      最近更新 更多