Я пытаюсь реализовать клиентскую программу UDP, которая получает файл с сервера, отправляя несколько запросов на чтение и получая небольшие части файла взамен (1400 байт, чтобы предотвратить фрагментацию). Каждый раз, когда я отправляю запрос, я настраивал вызов select () с таймаутом в 1 секунду. Если я получу ответ в течение этого времени, клиент отправит запрос на следующий фрагмент файла. В противном случае клиент повторно отправляет запрос на тот же фрагмент файла.
Проблема с этим последовательным дизайном заключается в том, что клиент ожидает ответа на КАЖДЫЙ запрос, прежде чем отправит следующий. Если есть даже небольшое соотношение потерь пакетов, это увеличит время, необходимое для отправки даже файла средней величины, до довольно неприемлемых уровней.
Я хотел бы спроектировать клиент так, чтобы он мог отправлять все запросы на чтение без ожидания ответов, одновременно выполняя цикл таймера и повторной передачи, который повторно отправляет отдельные запросы, которые не получают ответы. Тем не менее, я довольно новичок в программировании в целом, и не могу понять, как это сделать. Нужно ли открывать несколько сокетов одновременно и запускать разные циклы на каждом? Или есть более простой способ сделать это?
Мой текущий код (простите за беспорядок):
def read_service_loop(self):
"""Loop governing the timing, checking, and retransmission or processing of read service. """
#Increment start_position each time packet sent, send a read request packet for each new position.
#Expect to receive a read_response packet for each time read request sent.
recv_data = None
print("Sending request to server to read and receive file...")
start_position = 0
while(self.eof == False):
print("Reading from byte " + str(start_position))
num_retransmits = 0
#Loop for retransmissions of the same start position
while(num_retransmits < 60):
num_retransmits = num_retransmits + 1
self.send_read_request(start_position)
input_socket = [self.client_socket]
inputready,outputready,exceptready = select.select(input_socket,[],[], 1)
if (inputready == []):
continue
else:
recv_data = self.client_socket.recv(self.buffer_)
bit_signature = recv_data[0:4]
response_type = recv_data[4:8]
recv_payload = recv_data[8:]
if bit_signature != "\x00\x00\x00\r":
self.recv_invalid_response(recv_data, "bit_signature")
continue
else:
if response_type == "\x00\x00\x00\x02":
#Packet is valid, proceed to recv_read_response to append this bit of file received into local_filename
self.file_append = open(self.local_filename, 'r+b')
self.recv_read_response(recv_payload)
break
else:
self.recv_invalid_response(recv_data, "response_type")
continue
start_position = start_position + self.NUM_BYTES_TO_READ
if (num_retransmits >= 60):
print ("Exceeded number of retransmissions allowed. Exiting program.")
sys.exit()
return