UDP文件传输程序中的定时器和重新传输(使用低级套接字)



我正在尝试实现一个UDP客户端程序,该程序通过发送多个读取请求并接收文件的小块作为回报(1400字节,以防止碎片)来从服务器接收文件。每次发送请求时,我都会设置一个select()调用,超时时间为1秒。如果我在该时间内收到响应,客户端将继续发送对下一段文件的请求。否则,客户端将重新发送对相同文件的请求。

这种顺序设计的问题是,客户端在发送下一个请求之前,要等待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 != "x00x00x00r":
            self.recv_invalid_response(recv_data, "bit_signature")
            continue
            else:
            if response_type == "x00x00x00x02":
                #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

您想要实现的被称为"滑动窗口",就像TCP一样。这会很复杂,因为你需要考虑往返时间。它仍在发展中,看看不同操作系统的TCP实现如何具有不同的性能。也许你可以找到一些已经实现它的库

有没有理由不使用TCP?

最新更新