2010-12-07 2 views
1

Вот моя беда:Нужна лучший способ ожидания между отправкой и получением, UdpClient

У меня есть UdP класса, который позволит мне отправлять и получать данные от игрового сервера.

Но я обнаружил, что сервер допускает только один запрос на 500 мс на одного клиента. , поэтому, если я отправляю два запроса в строке, сервер отвечает только на первый, и у меня нет способа узнать, что я не получу второй ответ.

Поэтому я сделал Mutex для защиты части отправки, когда я отправляю данные, я использую поток для блокировки мьютекса 500 мс.

Этот класс используется thread, поэтому я использую мьютекс.

Но это не работает действительно хорошо, когда-то получаю застревание.

Я просто хочу знать, есть ли у кого-то лучший способ сделать это.

Спасибо и простите за мой английский.

EDIT: Я не могу использовать протокол tcp, мне нужно сделать это с помощью udp. Мне также нужен оптимальный способ, мне нужно получить данные приема как можно скорее. Я смотрю каждую тему в сети, которую я нашел на udp и потоковом, но не нашел этого конкретного случая.

ответ

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

С UDP вы никогда не должны предполагать, что получите ответ на любое отправленное вами сообщение. Вы также не должны предполагать, что сообщение действительно будет получено или что несколько сообщений будут получены в том же порядке, который вы отправляете. Вот почему UDP действительно подходит только для протоколов, которые могут терпеть потерю информации. Если вы хотите сохранить целостность, вам необходимо разрешить повторы, и в этот момент вам, вероятно, было бы лучше использовать TCP (при условии, что у вас был выбор в этом вопросе.)

Без дополнительной информации о деталях протокола, трудно рекомендовать хорошее решение. Если это простой стиль сообщения «статус-опрос», одним из вариантов является просто отправлять сообщения опроса с фиксированным интервалом и обрабатывать ответы по мере их поступления, игнорируя любое отношение, которое ответы могут иметь к отправляемым сообщениям.

+0

Я отредактирован, чтобы быть более конкретным. Мне нужна связь между отправленным и полученным сообщением, потому что я привязываю данные к winform. У меня нет доступа к моему коду прямо сейчас, но я могу позже, спросите меня, хотите ли вы. – Mackhdo 2010-12-07 16:50:44

+0

@Mackhdo, к сожалению, если служба, с которой вы подключаетесь, не отвечает своевременно и надежно, вы не можете многого не повторять, пока не получите ответ. Если повтор занимает слишком много времени, это проблема, которая может быть решена только на службе. – 2010-12-07 16:54:27

+0

Я знаю, я просто ищу хороший и лучший способ сделать это, потому что я не могу ожидать никакой помощи или изменения от поставщика услуги – Mackhdo 2010-12-07 17:04:25

0

Как указывали другие, нельзя предположить, что будет передано сообщение UDP. Вероятно, это вызывает зависание вашего кода при приеме. Возможно, просто установка Socket's ReceiveTimeout будет достаточно хорошим для вас.

Или вы можете настроить (несколько более сложный) метод отправки сообщений в очередь, отправляя их только каждые 500 мс и повторять их через определенное время, пока не получите ответ. Если бы я шел по этому маршруту, я бы разработал вокруг этих общих пунктов:

  • Использовать асинхронный UDP.
  • Создайте структуру/класс для фактической информации для отправки/получения (скажем, MsgObject), включая информацию о последнем его передаче.
  • Используйте этот объект MsgObject как объект AsyncState.
  • Управление потокобезопасной очередью/списком всех активных объектов MsgObjects. то есть сообщения, которые были запрошены для отправки, но ответ не получен.
  • У вас есть простой таймер для периодической проверки очереди/списка (не чаще, чем каждые 500 мс в вашем случае), чтобы узнать, есть ли новое сообщение для отправки, или тот, который должен быть повторно отправлен.
  • В асинхронной функции приема удалите объект MsgObject, который получил ответ из очереди/списка.

 Смежные вопросы

  • Нет связанных вопросов^_^