How can I send a file through a socket?

2

I'm doing a little chat with sockets in python, I'm trying to make it possible to send files through the chat, I thought about this to send the file:

file = open("file.txt", "rb")
content = file.readlines(1024)
sock.send(content)
file.close()

and this to receive:

file = open("file.txt", "wb")
file.write(sock.recv(1024))
file.close()

(these are not the real codes, it's just the basics so I do not have to complicate myself by writing here) the problem is that the variable content is a list and can not be sent by the socket.

    
asked by binario_newbie 10.08.2018 в 02:33
source

2 answers

3

If you're just going to send the file, it does not make much sense that you use readlines , apart from being inefficient to create a list and having to iterate over the file looking for line ends, it does not really add anything.

To send the file we can simply open it in binary mosenddo and with a while iterate to read it in fragments using read . A very simplified example of a server that sends a file to a client could be: send

Server:

import socket


HOST = '' 
PORT = 50007
CHUNK_SIZE = 5 * 1024
FILE = "example.txt"

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen(1)
    conn, addr = s.accept()
    with conn:
        with open(FILE, 'rb') as f:
            data = f.read(CHUNK_SIZE)
            while data:
                conn.sendall(data)
                data = f.read(CHUNK_SIZE)

Client:

import socket


HOST = ''
PORT = 50007
CHUNK_SIZE = 5 * 1024
FILE = "example2.txt"

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))

    with open(FILE, "wb") as f:        
        chunk = s.recv(CHUNK_SIZE)

        while chunk:
            f.write(chunk)
            chunk = s.recv(CHUNK_SIZE)

If using Python> = 3.5 you can use socket.socket.sendfile which is considerably more efficient if the operating system implements os.sendfile , otherwise it will use send :

import socket


HOST = '' 
PORT = 50007
CHUNK_SIZE = 5 * 1024
FILE = "example.txt"

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.bind((HOST, PORT))
    s.listen(1)
    conn, addr = s.accept()
    with conn:
        with open(FILE, 'rb') as f:
            conn.sendfile(f)
    
answered by 10.08.2018 / 04:33
source
0

Try sending each position on the list.

You can use len() for it or guide you from the following code:

def mysend(self, msg):
    totalsent = 0
    while totalsent < MSGLEN:
        sent = self.sock.send(msg[totalsent:])
        if sent == 0:
            raise RuntimeError("socket connection broken")
        totalsent = totalsent + sent
    
answered by 10.08.2018 в 03:24