我正在尝试实现一个UDP客户端程序,它通过发送多个读取请求并接收文件的一小部分(1400字节,以防止碎片)从服务器接收文件。每次发送请求时,我都会设置一个超时为1秒的select()调用。如果我在该时间内收到响应,则客户端继续发送下一个文件的请求。否则,客户端会重新发送同一文件的请求。
此顺序设计的问题是客户端在发送下一个请求之前等待EACH请求被响应。如果数据包丢失的比例很小,这会增加将中等大小的文件发送到相当不可接受的水平所需的时间。
我想将客户端设计为能够在不等待响应的情况下发送所有读取请求,同时运行定时器和重新发送循环,重新发送未接收响应的各个请求。但是,我对编码很新,而且似乎无法弄清楚如何做到这一点。我是否需要一次打开几个套接字并在每个套接字上运行不同的循环?或者有更简单的方法吗?
我目前的代码是(原谅混乱):
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
答案 0 :(得分:1)
您要实现的内容称为“滑动窗口”,就像TCP一样。这将很复杂,因为您需要考虑往返时间。它仍在不断发展,看看不同操作系统的TCP实现如何具有不同的性能。也许你可以找到一些已经实现它的库。
有什么理由不使用TCP?