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

发布于 2024-10-06 22:57:17 字数 413 浏览 6 评论 0原文

这是我的麻烦:

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

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

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

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

但这并不是很好,有时接收会卡住。

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

谢谢你,对我的英语感到抱歉。

编辑: 我无法使用 tcp 协议,我需要使用 udp 来完成此操作。 我还需要一种最佳方法,我需要尽快将接收数据发送到视图表单。 我查看了网上发现的有关 udp 和线程的每个主题,但没有找到这种特殊情况。

Here's my trouble:

I have a udp class that allow me to send and receive data from a gameserver.

But i found that the server allow only one request per 500ms per client.
so if i send two request in a row, the server respond only to the first one, and i have no way to know that i won't get the second answer.

So i made a Mutex to protect the send part, when i send data, i use a thread to block the mutex 500ms.

This class is used by thread, that's why i use mutex.

But this doesn't work really good, sometime the receive get stuck.

I just want to know if someone have a better way to do this.

Thank you and sorry for my english.

EDIT:
I can't use tcp protocol, i need to do this with udp.
I also need an optimal way, i need to get the receive data asap to the viewform.
I watch every single topic on the net i found on udp and threading, but don't find this particular case.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不再让梦枯萎 2024-10-13 22:57:17

如果您知道只能以一定频率发送,为什么不发送阻塞呼叫。然后睡规定的时间。

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();
    }
  }
}

If you know you can only send with some frequency, why not send calls blocking. And then sleep for the required time.

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();
    }
  }
}
2024-10-13 22:57:17

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

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

With UDP, you should never assume that you will get a response to any given message you send. You should also not assume that the message will actually be received or that multiple messages will be received in the same order you send them. That's why UDP is really only suited to protocols that can tolerate loss of information. If you want to maintain integrity, you need to allow for retries, at which point you probably would've been better off using TCP (assuming you had a choice in the matter.)

Without more information on the details of the protocol, it's hard to recommend a good solution. If it's a simple 'status poll' style of message, one option is to simply send the polling messages at a fixed interval and handle the responses as they arrive, ignoring any relation the responses might have to the messages being sent.

伴我老 2024-10-13 22:57:17

正如其他人指出的那样,不能假设将传递 UDP 消息。这可能会导致您的代码在接收时挂起。也许只需设置套接字的 ReceiveTimeout 就会对于你的应用来说足够好。

或者您可以设置一种(稍微复杂一些)方法,对要发送的消息进行排队,每 500 毫秒仅发送一条消息,并在一段时间后重试,直到收到响应。如果我选择这条路线,我会围绕以下一般要点进行设计:

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

As others have pointed out, it can't be assumed that a UDP message will be delivered. This is probably causing the hanging of your code on the receive. Maybe simply setting the Socket's ReceiveTimeout will be good enough for you're application.

Or you could setup a (somewhat more complex) method of queuing messages to send, only sending one every 500ms, and retrying them after a certain amount of time until you've gotten a response. If I were going this route, I'd design around these general points:

  • Use Asynchronous UDP.
  • Build a struct/class for the actual information to send/receive (say, MsgObject), Including information about the last time it was transmitted.
  • Use this MsgObject as your AsyncState object.
  • Manage a thread-safe queue/list of all active MsgObjects. i.e. messages that have been requested to send, but no response has been received.
  • Have a simple timer to check the queue/list periodically (no more frequently than every 500ms in your case) to see if there's a new message to send or one that needs to be resent.
  • In the asynchronous receive function, remove the MsgObject that received the response from the queue/list.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文