c++ - recv() 正确使用 C++

标签 c++ loops recv

我正在用 C++ 开发我自己的 FTP 客户端,但我被困在函数 recv() 上。当我使用 recv() 获取数据时,它们可能不完整,因为我使用的是 TCP 协议(protocol),所以我必须在 loop 中使用 recv。问题是,当我在收到所有应收到的内容后调用 recv 时,服务器 block ,我的程序被卡住了。 我不知道我要接收多少字节,所以我无法控制它并在它完成时停止它。我现在发现了两个不太优雅的解决方案:

  1. 是使用 string.substr() (或 TR1 正则表达式)来查找需要的 表达式,然后在它阻塞之前停止调用 recv
  2. 第二个是 设置timeval结构,然后通过控制socket setsockopt() 函数。问题是我能得到的响应时间很长 不完整的损坏数据。

问题是,是否有任何简洁优雅的解决方案?

最佳答案

显而易见的事情是提前传输要接收的消息的长度(许多协议(protocol),例如 HTTP 都这样做,以解决完全相同的问题)。这样,您就知道当您收到金额 X 时,就不会再收到了。

这在 99.9% 的情况下都可以正常工作,但在 0.1% 的情况下会发生灾难性的失败,例如服务器对您撒谎或服务器意外崩溃或有人绊倒网络电缆(或发生类似情况)。可悲的是,TCP 建立的“连接”是一种幻觉,您没有太多的方法来检测连接何时断开。另一端可能会掉线,您不会注意到任何事情,除非您尝试发送并收到错误(或直到几个小时后)。

因此,您还需要一个备份策略,以防万一情况不如预期。您可以使用 selectpoll 来了解数据何时可用,这样您就不会永远阻塞永远不会收到的消息。

使用线程来解决末端阻塞问题(如其他答案中所建议的那样)不是一个很好的选择,因为阻塞不是实际问题。实际问题是你不知道什么时候到达传输结束。在传输结束时让工作线程阻塞会“起作用”,但会使工作线程无限期地阻塞,消耗资源,并具有不确定的、依赖于系统的命运。

你不能在退出前join线程,因为它被阻塞了(所以尝试join会死锁你的主线程)。当您的进程退出并且套接字关闭时,线程将解除阻塞,但(至少在一些操作系统上,例如 Windows)会在之后立即终止。这可能不会做太多坏事,但以不受控制的方式终止线程总是不如让线程正确退出更可取。在其他操作系统上,您可能还有一个挥之不去的线程。

关于c++ - recv() 正确使用 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22327554/

相关文章:

python - python中的循环缩进

c - 如何跳过 GDB 中循环的多次迭代?

c - 通过 C 中的套接字与服务器的多个连接

Python 阻塞 recv 返回的数据少于请求的数据

python - 选择后没有数据可用于接收

c++ - gcc 中 Unresolved 重载函数类型

arrays - 如果数组为空,VBA 继续

c++ - 通过复制捕获 Lambda 函数会导致数据损坏

c++ - C++ 中的 switch 语句

c++ - Linux 上 Poco::Logger 的编译器错误 - 函数声明被视为宏