Передача содержимого файла по сети

Не могу понять, почему не записывается файл на стороне сервера при приеме бинарной информации от клиента? В чем может быть проблема?

# SERVER 
import socketserver as ss

HOST, PORT = "127.0.0.1", 50007
class superTCPUnlimitedServer(ss.BaseRequestHandler):

    def setup(self):
        pass

    def handle(self):
        # self.request is the TCP socket connected to the client
        print("Server connected by ", self.client_address[0])

        with open('input.tst', 'ab') as f:
            self.data = self.request.recv(1024).strip()  
            while self.data:
                print("Начало приема файла")
                f.write(self.data)
                self.data = self.request.recv(1024).strip() 
        print("Файл закрыт")    
        print("{} wrote:".format(self.client_address[0]))
        print("Файл получен")
        # just send back the same data, but upper-cased
        self.request.sendall(bytes("файл получен", "utf-8"))

    def finish(self):
        pass    

with ss.ThreadingTCPServer((HOST, PORT), superTCPUnlimitedServer) as server:
    server.serve_forever() # server.shutdown() останавливает цикл serve_forever()
# CLIENT
import socket
import threading


HOST, PORT = "127.0.0.1", 50007
data = "Hello super server"
    
# Create a socket (SOCK_STREAM means a TCP socket)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
    # Connect to server and send data
    sock.connect((HOST, PORT))
    with open("001055.test", "rb") as file:
        sock.send(file.read())  
    
    # Receive data from the server and shut down
    received = str(sock.recv(1024), "utf-8")
    print("Sent:     {}".format(data))
    print("Received: {}".format(received))

Ответы (1 шт):

Автор решения: Анатолий

Ключевая строка:

self.data = self.request.recv(1024).strip() 

В данном случае, при очередной итерации цикла while, когда все байты уже приняты, self.request.recv(1024) бесконечно ожидает новую порцию данных. Было принято решение добавить атрибут CHUNK класса SuperTCPUnlimitedServer и в цикле while сравнивать длину CHUNK с размером принятых данных. Если очередная порция данных меньше атрибута CHUNK, это говорит о том что поступила последняя порция данных. Решение не оптимальное. Проблемы возникнут если вдруг размер получаемого файла кратен значению CHUNK.

Итоговый код:

import socketserver as ss

HOST, PORT = "127.0.0.1", 50007



class SuperTCPUnlimitedServer(ss.BaseRequestHandler):
    CHUNK = 1024
    def setup(self):
        pass

    def handle(self):

        # self.request is the TCP socket connected to the client
        print("Server connected by ", self.client_address[0])
        with open('input.ff', 'ab') as f:
            self.data = self.request.recv(self.CHUNK)
            while 1:
                if len(self.data) < self.CHUNK:
                    f.write(self.data)
                    break
                f.write(self.data)
                self.data = self.request.recv(self.CHUNK)
        print("Файл закрыт")
        print("{} wrote:".format(self.client_address[0]))
        print("Файл получен")
        # just send back the same data, but upper-cased
        self.request.sendall(bytes("файл получен", "utf-8"))

    def finish(self):
        pass

with ss.ThreadingTCPServer((HOST, PORT), SuperTCPUnlimitedServer) as server:
    server.serve_forever()  
→ Ссылка