UDP-клиент отправляет пинг раз в секунду, а также печатает что-нибудь отправленное на него? - PullRequest
0 голосов
/ 27 мая 2018

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

Для начала у меня есть сервер UDP Echo, который действует как игровой сервер.Каждый раз, когда ему отправляется пинг, он добавляет IP-адрес и порт источника в список «подключенных клиентов» и отправляет этот точный пинг всем в списке, кроме отправителя.Это работает довольно хорошо, потому что реагирует на получение сообщения, поэтому всегда может просто прослушать.Однако проблема с клиентом заключается в том, что мне нужно постоянно посылать пинги и одновременно слушать.

В настоящее время мой клиент выглядит так:

import socket
from time import sleep
from contextlib import contextmanager

UDP_IP_ADDRESS = "127.0.0.1"
UDP_PORT_NO = 14004
Message = b"Hello World, From Client B"


@contextmanager
def socket_ctx():
    """ Context Manager for the socket. Makes sure the socket will close regardless of why it exited."""
    my_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # Assign IP address and a RANDOM available port number to socket
    my_socket.bind(('127.0.0.1', 0))
    try:
        # Let the rest of the app use the socket and wait for it to finish
        yield my_socket
    finally:
        my_socket.close()


def send_data(client_sock):
    client_sock.sendto(Message, (UDP_IP_ADDRESS, UDP_PORT_NO))


def listen(client_sock):
    print(client_sock.recvfrom(100))



with socket_ctx() as sock:
    while True:
        send_data(sock)
        listen(sock)
        sleep(2)

В настоящее время он отправляетпинг один раз, затем просто бездельничает, поскольку он, вероятно, слушает.Если случится так, что ответ получит ping, скажем, другой клиент отправит запрос ping на сервер, и сервер отправит запрос ping этому клиенту, он его услышит, напечатает и снова запустит цикл.Проблема в том, что без того, чтобы другой клиент отправлял что-то, чтобы вытряхнуть это из прослушивания, он не отправляет свои эхо-запросы.

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

1 Ответ

0 голосов
/ 28 мая 2018

Вот как я могу реализовать сервер с режимом «получать и обрабатывать входящие UDP-сокеты, а также выполнять некоторые посылки пакетов раз в секунду».Обратите внимание, что здесь используется функция select() для мультиплексирования двух задач, а не асинхронный ввод-вывод;надеюсь, это нормально.

import socket
import select
import time

UDP_IP_ADDRESS = "127.0.0.1"
UDP_PORT_NO = 14004
Message = b"Hello World, From Client B"

udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_socket.bind(('127.0.0.1', 0))
print "UDP socket is listening for incoming packets on port", udp_socket.getsockname()[1]

# When we want to send the next periodic-ping-message out
nextPingTime = time.time()

while True:
   secondsUntilNextPing = nextPingTime - time.time();
   if (secondsUntilNextPing < 0):
      secondsUntilNextPing = 0

   # select() won't return until udp_socket has some data
   # ready-for-read, OR until secondsUntilNextPing seconds 
   # have passed, whichever comes first
   inReady, outReady, exReady = select.select([udp_socket], [], [], secondsUntilNextPing)

   if (udp_socket in inReady):
      # There's an incoming UDP packet ready to receive!
      print(udp_socket.recvfrom(100))

   now = time.time()
   if (now >= nextPingTime):
      # Time to send out the next ping!
      print "Sending out scheduled ping at time ", now
      udp_socket.sendto(Message, (UDP_IP_ADDRESS, UDP_PORT_NO))
      nextPingTime = now + 1.0   # we'll do it again in another second
...