需要一种更好的方法来在发送和接收之间等待,UDPclient

时间:2010-12-07 16:38:13

标签: c# multithreading udpclient

这是我的麻烦:

我有一个udp类,允许我从游戏服务器发送和接收数据。

但我发现服务器每个客户端每500毫秒只允许一个请求。 所以,如果我连续发送两个请求,服务器只响应第一个请求,我无法知道我不会得到第二个答案。

所以我制作了一个Mutex来保护发送部分,当我发送数据时,我使用一个线程阻止互斥锁500ms。

此类由线程使用,这就是我使用互斥锁的原因。

但这种方法效果不好,有时接收卡住了。

我只是想知道某人是否有更好的方法来做到这一点。

谢谢你,对不起我的英语。

编辑: 我不能使用tcp协议,我需要用udp做这个。 我还需要一种最佳方式,我需要尽快获得视图形式的接收数据。 我在udp和线程上找到网上的每一个主题,但没有找到这个特殊情况。

3 个答案:

答案 0 :(得分:1)

使用UDP,您绝不应该假设您将收到对您发送的任何给定消息的响应。您也不应该假设将实际收到消息,或者将按照您发送的相同顺序接收多条消息。这就是为什么UDP真的只适合能够容忍信息丢失的协议。如果你想保持完整性,你需要允许重试,此时你可能会更好地使用TCP(假设你可以选择此事。)

如果没有关于协议细节的更多信息,很难推荐一个好的解决方案。如果它是一种简单的“状态轮询”式消息,一种选择是简单地以固定间隔发送轮询消息并在响应到达时处理它们,忽略响应可能对正在发送的消息的任何关系。

答案 1 :(得分:1)

如果您知道只能以某种频率发送,为什么不发送阻止呼叫。然后睡觉所需的时间。

class UDP {
  int _lastTime = 0;
  int MIN_DELAY = 500;

  public void send() {
    lock(this) {
      int duration = now() - _lastTime;
      if (duration < MIN_DELAY) {
        sleep(MIN_DELAY - duration);  
      }
      realSend();
      _lastTime = now();
    }
  }
}

答案 2 :(得分:0)

正如其他人所指出的,不能假设将传递UDP消息。这可能导致您的代码挂在接收上。也许简单地设置Socket的ReceiveTimeout对于你的申请来说已经足够了。

或者您可以设置(稍微复杂一点)排队发送消息的方法,每500ms发送一次,并在一定时间后重试它们,直到您收到响应。如果我走这条路,我会围绕这些一般要点进行设计:

  • 使用异步UDP。
  • 为要发送/接收的实际信息(例如MsgObject)构建结构/类,包括有关上次传输的信息。
  • 使用此MsgObject作为AsyncState对象。
  • 管理所有活动MsgObjects的线程安全队列/列表。即已请求发送的消息,但未收到任何响应。
  • 有一个简单的计时器来定期检查队列/列表(不比你的情况每500毫秒更频繁),以查看是否有要发送的新消息或需要重新发送的消息。
  • 在异步接收函数中,从队列/列表中删除收到响应的MsgObject。