Пример #1
0
 def server_run(self):
     while True:
         self.send_data()  # 发送数据
         readable = select.select([self.socket], [], [], 1)[0]  # 非阻塞方法
         if len(readable) > 0:  # 接收ACK数据
             rcv_ack = self.socket.recvfrom(
                 self.ack_buf_size)[0].decode().split()[0]
             if self.send_base <= int(
                     rcv_ack) < self.next_seq:  # 收到ack,则标记为已确认且超时计数为0
                 print('服务器:收到有用ACK' + rcv_ack)
                 self.ack_seqs[int(rcv_ack)] = True  # 设为已接受
                 if self.send_base == int(rcv_ack):  # 收到的ack为最小的窗口序号
                     self.slide_send_window()  # 则滑动窗口
             else:
                 print('服务器:收到无用ACK' + rcv_ack)
         for seq in self.time_counts.keys():  # 每个未接收的分组的时长都加1
             if not self.ack_seqs[seq]:  # 若未收到ACK
                 self.time_counts[seq] += 1  # 则计次+1
                 if self.time_counts[seq] > self.time_out:  # 触发超时操作
                     self.handle_time_out(seq)  # 超时处理
         if self.send_base == len(self.data):  # 数据传输结束
             self.socket.sendto(Host.make_pkt(0, 0),
                                self.remote_address)  # 发送传输结束包
             print('服务器:数据传输结束')
             break
Пример #2
0
 def handle_time_out(self, time_out_seq):
     print('超时重传:' + str(time_out_seq))
     self.time_counts[time_out_seq] = 0  # 重新定时
     if random.random() > self.pkt_loss:  # 随机发送数据包
         self.socket.sendto(
             Host.make_pkt(time_out_seq, self.data[time_out_seq]),
             self.remote_address)
Пример #3
0
 def client_run(self):
     while True:
         readable = select.select([self.socket], [], [], 1)[0]  # 非阻塞接受
         if len(readable) > 0:
             rcv_data = self.socket.recvfrom(self.data_buf_size)[0].decode()
             rcv_seq = rcv_data.split()[0]  # 提取数据包序号
             rcv_data = rcv_data.replace(rcv_seq + ' ', '')  # 提取数据包数据
             if rcv_seq == '0' and rcv_data == '0':  # 收到传输数据结束的标志
                 print('客户端:传输数据结束')
                 break
             print('客户端:收到数据' + rcv_seq)
             if self.rcv_base - self.rcv_window_size <= int(
                     rcv_seq) < self.rcv_base + self.rcv_window_size:
                 if self.rcv_base <= int(
                         rcv_seq
                 ) < self.rcv_base + self.rcv_window_size:  # 窗口内
                     self.rcv_data[int(
                         rcv_seq)] = rcv_data  # 失序的数据到来:缓存+发送ack
                     if int(
                             rcv_seq
                     ) == self.rcv_base:  # 按序数据的到来:滑动窗口并交付数据(清除对应的缓冲区)
                         self.slide_rcv_window()
                 if random.random() >= self.ack_loss:
                     self.socket.sendto(Host.make_pkt(int(rcv_seq), 0),
                                        self.remote_address)
                 print('客户端:发送ACK' + rcv_seq)
Пример #4
0
 def handle_time_out(self):
     print('超时,开始重传')
     self.time_count = 0  # 超时计次重启
     for i in range(self.send_base, self.next_seq):  # 发送空中的所有分组
         if random.random() > self.pkt_loss:  # 概率性重传
             self.socket.sendto(Host.make_pkt(i, self.data[i]),
                                self.remote_address)
         print('数据已重发:' + str(i))
Пример #5
0
 def send_data(self):
     if self.next_seq == len(self.data):  # data数据已全部被发送过
         print('服务器:发送完毕,等待确认')
         return
     if self.next_seq - self.send_base < self.window_size:  # 窗口中仍有可用空间
         if random.random() > self.pkt_loss:  # 随机产生丢包行为
             self.socket.sendto(
                 Host.make_pkt(self.next_seq, self.data[self.next_seq]),
                 self.remote_address)
         print('服务器:成功发送数据' + str(self.next_seq))
         self.next_seq = self.next_seq + 1
     else:  # 窗口中无可用空间
         print('服务器:窗口已满,暂不发送数据')
Пример #6
0
 def send_data(self):
     if self.next_seq == len(self.data):  # 判断是否还有缓存数据可以发送
         print('服务器:发送完毕,等待确认')
         return
     if self.next_seq < self.send_base + self.send_window_size:  # 窗口中仍有可用空间
         if random.random() > self.pkt_loss:
             self.socket.sendto(
                 Host.make_pkt(self.next_seq, self.data[self.next_seq]),
                 self.remote_address)
         self.time_counts[self.next_seq] = 0  # 设置计时器
         self.ack_seqs[self.next_seq] = False  # 设置为未接受确认包
         print('服务器:发送数据' + str(self.next_seq))
         self.next_seq += 1
     else:  # 窗口中无可用空间
         print('服务器:窗口已满,暂不发送数据')
Пример #7
0
 def server_run(self):
     while True:
         self.send_data()  # 发送数据逻辑
         readable = select.select([self.socket], [], [], 1)[0]
         if len(readable) > 0:  # 接收ACK数据
             rcv_ack = self.socket.recvfrom(
                 self.ack_buf_size)[0].decode().split()[0]
             print('收到客户端ACK:' + rcv_ack)
             self.send_base = int(rcv_ack) + 1  # 滑动窗口的起始序号
             self.time_count = 0  # 计时器计次清0
         else:  # 未收到ACK包
             self.time_count += 1  # 超时计次+1
             if self.time_count > self.time_out:  # 触发超时重传操作
                 self.handle_time_out()
         if self.send_base == len(self.data):  # 判断数据是否传输结束
             self.socket.sendto(Host.make_pkt(0, 0),
                                self.remote_address)  # 发送结束报文
             print('服务器:发送完毕')
             break
Пример #8
0
 def client_run(self):
     while True:
         readable = select.select([self.socket], [], [], 1)[0]  # 非阻塞接收
         if len(readable) > 0:  # 接收到数据
             rcv_data = self.socket.recvfrom(self.data_buf_size)[0].decode()
             rcv_seq = rcv_data.split()[0]  # 按照格式规约获取数据序号
             rcv_data = rcv_data.replace(rcv_seq + ' ', '')  # 按照格式规约获取数据
             if rcv_seq == '0' and rcv_data == '0':  # 接收到结束包
                 print('客户端:传输数据结束')
                 break
             if int(rcv_seq) == self.exp_seq:  # 接收到按序数据包
                 print('客户端:收到期望序号数据:' + str(rcv_seq))
                 self.write_data_to_file(rcv_data)  # 保存服务器端发送的数据到本地文件中
                 self.exp_seq = self.exp_seq + 1  # 期望数据的序号更新
             else:
                 print('客户端:收到非期望数据,期望:' + str(self.exp_seq) + '实际:' +
                       str(rcv_seq))
             if random.random() >= self.ack_loss:  # 随机丢包发送数据
                 self.socket.sendto(Host.make_pkt(self.exp_seq - 1, 0),
                                    self.remote_address)