1

这是我的麻烦:

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

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

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

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

但这并不能很好地工作,有时接收会卡住。

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

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

编辑:我不能使用 tcp 协议,我需要使用 udp 执行此操作。我还需要一种最佳方式,我需要尽快将接收数据发送到视图。我在网上看到了关于 udp 和线程的每一个主题,但没有找到这种特殊情况。

4

3 回答 3

1

使用 UDP,您永远不应该假设您会收到对您发送的任何给定消息的响应。您也不应该假设消息实际上会被接收,或者多个消息将按照您发送它们的相同顺序接收。这就是为什么 UDP 实际上只适用于可以容忍信息丢失的协议。如果要保持完整性,则需要允许重试,此时使用 TCP 可能会更好(假设您在这件事上有选择权。)

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

于 2010-12-07T16:44:21.310 回答
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();
    }
  }
}
于 2010-12-07T16:53:33.373 回答
0

正如其他人指出的那样,不能假设将传递 UDP 消息。这可能导致您的代码在接收时挂起。也许简单地设置 Socket 的ReceiveTimeout对你的应用程序来说已经足够了。

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

  • 使用异步 UDP。
  • 为要发送/接收的实际信息(例如MsgObject)构建一个结构/类,包括有关上次传输时间的信息。
  • 将此 MsgObject 用作​​您的 AsyncState 对象。
  • 管理所有活动 MsgObjects 的线程安全队列/列表。即已请求发送但未收到响应的消息。
  • 有一个简单的计时器来定期检查队列/列表(在您的情况下不超过每 500 毫秒),以查看是否有新消息要发送或需要重新发送。
  • 在异步接收函数中,从队列/列表中移除接收到响应的 MsgObject。
于 2010-12-07T17:31:17.287 回答