21 novembre, 2006

Invio file su socket in python

In questo post spiegherò come è possibile inviare un file attraverso
la rete utilizzando i socket python. Quello che andremo a costruire
è un piccolo server che rimarrà in ascolto per ricevere un file che
verrà inviato da un client il quale lo preleverà dal disco rigido e lo
invierà via socket.
Ecco il codice del serverino che chiamiamo receive.py


#! /usr/bin/env/python

import socket
import sys

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 9900))
sock.listen(1)

filename = sys.argv[1]

s, addr = sock.accept()
file = open(filename, 'wb')
while 1:
data = s.recv(1024)
if not data: break
file.write(data)
file.close()
s.close()

In pratica non fa altro che mettersi in ascolto sulla porta 9900 ed
aspettare la connessione da parte del client. Non appena il client
si connette, crea un file con il nome che gli è stato passato come
parametro e ci scrive dentro i dati inviatigli.

Vediamo ora il codice del client che chiamiamo send.py:

#! /usr/bin/env/python

import sys
import socket

filename = sys.argv[1]
host = sys.argv[2]

file = open(filename, 'rb')
sock = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
sock.connect((host, 9900))

while 1:
data = file.read(1024)
if not data: break
sock.sendall(data)
file.close()
sock.close()


Il client apre il file passatogli come primo parametro e lo invia al
server (secondo parametro).
Come si può vedere si usa una normale sendall.
La documentazione python a riguardo potrebbe essere fuorviante.
Infatti viene indicato come sendall(string[, flags])
Cioè il primo parametro viene indicato come string mentre noi
vogliamo inviare un file binario generico. In realtà il metodo
funziona comunque perché la stringa in questo caso è intesa
un po come un array di char ovvero un array di bytes ;)

2 commenti:

  1. Anonimo7:52 PM

    mi potrebbe venir utile;)

    RispondiElimina
  2. ciao, il tuo codice mi è utilissimo, potresti pero aiutarmi con quest'errore?

    IndexError: list index out of range

    RispondiElimina