【问题标题】:How do I make a code loop while waiting for a message with 'recv'如何在等待带有“recv”的消息时进行代码循环
【发布时间】:2017-07-13 18:13:57
【问题描述】:

我正在编写一个简单的 C 游戏,它通过网络接受关键输入。因为这是我第一次在 C 中处理套接字,所以我在某些功能上遇到了一些问题。这个名为“recv”的函数似乎在等待 TCP 连接中的任何网络消息,直到接收到数据。问题是,由于这会在没有消息的情况下“冻结”程序,因此我应该在无限循环中运行的正常游戏代码将无法正常工作。有没有办法让我在等待网络消息的同时运行游戏?

while (1) //Infinite 'game loop' start
    {
    read_size = recv(newsockfd , client_message , 2000 , 0);
    if(read_size > 0)
         {
         //Do something
         }
    //Game code here (Doesn't work when there are no incoming messages!)
    }

【问题讨论】:

  • 使套接字非阻塞?使用零超时轮询?线程?
  • 您可以使用select(带有超时)让您的任务进入睡眠状态。显然你应该使用多线程方法
  • 如果游戏没有做太多事情(例如,只是由计时器触发的一些更新步骤),您可以改为使用 select() 并在主循环中设置超时。跨度>
  • 我认为,对于相当简单(大多数)的情况,最干净的解决方案是使用 poll/select 进行轮询。非阻塞套接字通常是糟糕设计的标志,而多线程可能是矫枉过正。
  • ^^ @Ctx 所说的。虽然等待输入的额外线程肯定会起作用,但另一个线程中的“游戏循环”将需要任何输入,因此循环最终会“轮询”线程输出队列/无论如何。也可以为它投票/epoll/select。

标签: c sockets loops network-programming


【解决方案1】:

答案在一定程度上取决于后台处理必须做什么以及它必须运行的频率。如果您的后台处理是一项需要一直运行并且没有自然中断的连续任务,那么您可能需要一个线程。如果它只是必须定期发生的有限事件,那么您不需要线程,您需要pollselect

poll 更灵活,但select 有更简单的 API,但它们或多或少做同样的事情。您提供一组文件描述符、您感兴趣的事件和超时。

如果你在你的情况下使用select,你会把你的套接字放在读取文件描述符的集合中并提供一个合适的时间。当select 返回时,您的套接字上将有一些数据,或者超时将过期。

与非阻塞 IO 相比,使用select 的优势在于您可以轻松处理多个套接字,而不是在没有发生任何事情时在紧密循环中旋转,而是暂停您的进程。

【讨论】:

    【解决方案2】:

    使用多线程来解决这个问题。 recv 函数被阻塞,因此您不能使用单线程进行此操作。

    或者使用非阻塞套接字(没有超时)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-09
      • 1970-01-01
      • 1970-01-01
      • 2020-05-09
      • 1970-01-01
      • 2022-12-10
      • 1970-01-01
      • 2020-12-25
      相关资源
      最近更新 更多