Sterling Duchess
Sterling Duchess

Reputation: 2080

Python - Sending files over sockets

I have been trying to implement a small SERVER - CLIENT app but ran in to a errrr:

socket.error: [Errno 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied

Server:

class Server:
    gate = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    host = socket.gethostname()
    port = 0
    file = ''

    def __init__(self, port):
        self.port = port
        self.gate.bind((self.host, self.port))  
        self.listen()

    def listen(self):
        self.gate.listen(10)
        while True:
            add = self.gate.accept()
            self.reciveFileName()
            self.reciveFile()


    def reciveFileName(self):
        while True:
            data = self.gate.recv(1024)
            self.file = data

    def reciveFile(self):
        createFile = open("new_"+self.file, "wb")
        while True:
            data = self.gate.recv(1024)
            createFile.write(data)
        createFile.close()



a = Server(1111)

Client:

class Client:
    gateway = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #host = socket.gethostname()
    host = ''
    port = 0
    file = ''

    def __init__(self, host, port, file):
        self.port = port
        self.host = host
        self.file = file
        self.connect()

    def connect(self):
        self.gateway.connect((self.host, self.port))
        self.sendFileName()
        self.sendFile()

    def sendFileName(self):
        self.gateway.send("name:" + self.file)

    def sendFile(self):
        readByte = open(self.file, "rb")
        data = readByte.read()
        readByte.close()

        self.gateway.send(data)
        self.gateway.close()



a = Client('93.103.56.251', 1111, 'data.txt')

Upvotes: 3

Views: 11728

Answers (1)

phihag
phihag

Reputation: 287755

A server has one server socket that is used to accept incoming connections, and another socket for each of these connections. From your code:

self.gate.listen(10)
while True:
    add = self.gate.accept()
    self.reciveFileName() # which calls self.gate.recv()

Instead of operating on self.gate in reciveFilename and reciveFile (by the way, the proper spelling is receive), you should make these methods operate on the accepted connection, like this:

def listen(self):
    self.gate.listen(10)
    while True:
        conn,address = self.gate.accept()
        self.receiveFilename(conn)

def receiveFilename(self, sock):
    buf = sock.recv(1024)
    print('First bytes I got: ' + buf)

Also, reciveFilename currently listens forever on the socket. Instead, you must design a proper protocol that specifies when the filename is over and the file content begins. For example, you can let the file name end with b'\0' and let the server search for that byte.

Upvotes: 7

Related Questions