Тема: Клієт серверні додатки на Python
Всім доброго дня!
Отримав завдання написати клієнт сервер мовою програмування Python на протоколі передачі UDP з підтримкою алгоритму ARQ.
Потрібно переслати бінарний файл з клієнта на сервер за різних умов якості мережі.
Хочу попросити Вашої допомоги товариство, тому що зіткнувся з проблемами в логіці роботи моєї програми і не можу з цим впоратись.
Приводжу код клієна нижче...
from sys import argv as arguments
from sys import exit as end_program
from sys import stdin
from time import sleep as delay
from pickle import dumps
from pickle import loads
import socket
import os
import io
TIME_DELAY = {
    "s": 1,
    "ms": 1 * pow(10, -3),
    "mcs": 1 * pow(10, -6),
    "ns": 1 * pow(10, -9),
}
SOCKET = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
WINDOW_SIZE = 1000
BUFFER_SIZE = 1000
NUM_OF_DATA_BLOCK = 0
NUM_OF_DATA_BLOCK_COUNTER = 0
REQUEST = []
if len(arguments) != 3:
    print('Alarm! Pass ip and port arguments')
    end_program(1)
else:
    DST_ADDR = arguments[1], int(arguments[2])
def get_block_from_stdin(_window_size=None, _buffer_size=None):
    
    if _window_size is None:
        _window_size = 500
    if _buffer_size is None:
        _buffer_size = 1400
    
    global NUM_OF_DATA_BLOCK_COUNTER
    NUM_OF_DATA_BLOCK_COUNTER += 1
    
    _formed_block = []
    for i in range(_window_size):
        data = stdin.buffer.read(_buffer_size)
        if data:
            _formed_block.append(data)
        else:
            _formed_block.append(None)
            break
    return _formed_block
def flag_end():
    print("END")
    SOCKET.sendto(dumps("END"), DST_ADDR)
def sender(_formed_block):
    for num_of_data_part, part_of_data in enumerate(_formed_block):
        _numbered_formed_block = [NUM_OF_DATA_BLOCK, num_of_data_part, part_of_data]
        # print(_numbered_formed_block)
        SOCKET.sendto(dumps(_numbered_formed_block), DST_ADDR)
        delay(TIME_DELAY["mcs"])
def resender(_formed_block, _request_list):
    for index_of_data, data in enumerate(_formed_block):
        for request_index in _request_list:
            if index_of_data == request_index:
                _request_block = [NUM_OF_DATA_BLOCK, index_of_data, data]
                SOCKET.sendto(dumps(_request_block), DST_ADDR)
def answer_from_server():
    _b_answer, DST_ADDR = SOCKET.recvfrom(BUFFER_SIZE)
    _answer = loads(_b_answer)
    return _answer
break_flag = True
while break_flag:
    #numberpREQUESTet = 0
    block_of_data = get_block_from_stdin(WINDOW_SIZE, BUFFER_SIZE)
    if None in block_of_data:
        block_of_data.pop()
        break_flag = False
    block_of_data_is_send_success = True
    while block_of_data_is_send_success:
        sender(block_of_data)
        #"""
        request = answer_from_server()
        if request == "OK":
            NUM_OF_DATA_BLOCK += 1
            block_of_data_is_send_success = False
        else:
            resender(block_of_data, request)
        
        # """
    if not break_flag:
        flag_end()
        break
SOCKET.close()
print("Transmission is finished")
print("Blocks:", NUM_OF_DATA_BLOCK)
end_program()а тут код серверу....
from sys import argv as arguments
from sys import exit as end_program
from sys import stdout
from time import sleep as delay
from pickle import dumps
from pickle import loads
import socket
import time
import os
HOST = "localhost"
PORT = 9000
#PORT = int(arguments[1])
SOCKET = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
SOCKET.bind((HOST, PORT))
WINDOW_SIZE = 1000
BUFFER_SIZE = 1020
NO_DATA = 0
def receive(_window_size=None, _buffer_size=None):
    global _dst_addr
    global NO_DATA
    _packets = []
    _data = ""
    if _window_size is None:
        _window_size = 500
    if _buffer_size is None:
        _buffer_size = 1400
    for counter in range(_window_size):
        try:
            _data, _dst_addr = SOCKET.recvfrom(_buffer_size)
            if _dst_addr:
                SOCKET.settimeout(2)
            _packet = loads(_data)
            if _packet == "END":
                _packets = _packet
                break
            elif _packet[1] == 999:
                _packets.append(_packet)
                break
            else:
                _packets.append(_packet)
            NO_DATA = 0
        except socket.timeout:
            NO_DATA += 1
            # print("\r[", NO_DATA, "]", SOCKET.gettimeout(), "sec after", end="")
    return _packets, _dst_addr
wait = True
while wait:
    received_window = [None for i in range(WINDOW_SIZE)]
    success_receive = True
    while success_receive:
        #print("Wait for packets...")
        packets, dst_addr = receive(WINDOW_SIZE, BUFFER_SIZE)
        if packets == "END":
            wait = False
        else:
            for packet in packets:
                received_window[packet[1]] = [packet[1], packet[2]]
            request = [index_of_data for index_of_data, data in enumerate(received_window) if index_of_data is None]
            if len(request) == 0:
                SOCKET.sendto(dumps("OK"), dst_addr)
                for packet in received_window:
                    #print(packet)
                    #with open(NAME_FILE, "a") as FILE:
                    #    FILE.write(packet[1])
                    stdout.buffer.write(packet[1])
                success_receive = False
            else:
                SOCKET.sendto(dumps(request), dst_addr)
                request = []
            
            """
            retransmitted_packets = receive(len(request))
            for retransmitted_packet in retransmitted_packets:
                packet_number = retransmitted_packet[1]
                received_window[packet_number] = [packet_number, retransmitted_packet[2]]
            # """
SOCKET.close()
end_program()Програма запускається за допомогою команд в консолі Linux:
python3 UDPclientl.py 127.0.0.1 9000 < 1.jpg(filename)  -  запуск клієта
python3 UDPserverl.py 9000 > new.jpg(filename)   - запуск сервера
Бінарний файл генерується також в консолі за допомогою команд :
dd if=/dev/urandom of=file count=1024 bs=1048576 #generation 1gb
dd if=/dev/urandom of=file count=1024 bs=4096 #generation 4Mb file
Дуже прошу допомогти оскільки до здачі завдання залишилось всього 5 днів!!!
Зв'язатись можна через телеграм: @snnzr 
або поштою snihurnazar@gmail.com
Винагороду обговоримо приватно)