Python socket file transfer

Trying to create a simple file transfer with sockets in Python. I am stuck and it seems that I can not send part of the file.

Following some tips, I tried to send the last line of the file, so I can find out when to complete the connection.

But it happens that as soon as I send the first packet, the client never receives the rest.

Here you will see my code (server side):

import os import socket PORT = 8080 HOST = 'localhost' socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socket.bind((HOST,PORT)) socket.listen(10) conn, addr = socket.accept() print '\033[46m\033[34m\033[1mBienvenido al File Sender v.0.02 hecho en Python. Este programa permite enviar archivos a traves de tu maquina\033[0m' ANSI_RED = '\033[31m' ANSI_BLUE = '\033[34m' ESCAPEANSI = '\033[0m' def seleccion_path(): PATH = raw_input('\033[34m\033[1mSelect the Path (./ by default)').strip('n') if PATH == '': PATH = os.getcwd() print PATH, ESCAPEANSI acepta_path = raw_input('\033[34m\033[1mSi o No (S/N)').lower().strip(' ') if acepta_path == 's' or acepta_path == 'si': return PATH else: seleccion_path() def filesDir(path): files = os.listdir(PATH) for fl in files: i = int(files.index(fl))+1 print ANSI_RED + str(i)+ ')' + fl return files PATH = seleccion_path() print 'el PATH seleccionado es:', PATH + '\n' filesDir(PATH) fileSelected = int(raw_input(ANSI_BLUE + 'Select a file with the number').strip(' ').lower()) print PATH + filesDir(PATH)[fileSelected-1] fileToSend = open(PATH + filesDir(PATH)[fileSelected-1], 'rb') qLines = len(open(PATH + filesDir(PATH)[fileSelected-1], 'rb').readlines()) finalLine = cpfileToSend.readlines()[qLines-1] conn.send(finalLine) while True: data = conn.sendall(fileToSend.readline()) conf = conn.recv(1024) print conf if conf == 'OK': conn.close() fileToSend.close() break print '\033[43m File sent' #Finaliza el programa y deja los codigos ANSI cerrados print ESCAPEANSI exit() 

Here is the client:

 import os import socket PORT = 8080 HOST = 'localhost' socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socket.connect((HOST, PORT)) fname = open('./fileSent.pdf', 'w+') finalLine = socket.recv(1024) print finalLine while True: strng = socket.recv(2048) print 'aaaaa',strng fname.write(strng) if finalLine in strng: fname.write(strng) socket.send('OK') socket.close() fname.close() print 'Data received correctly' exit() 
+4
source share
2 answers

Finally, I was able to do this. The problem was in socket.recv (). I asked the application to execute several lines, but nothing came from the server. The client never executed lines below this, because it expected the data to continue executing the following lines. I rebuilt the code to handle this and it works great. Definitely love Python :)

Server side:

 import os import socket PORT = 8080 HOST = 'localhost' socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socket.bind((HOST,PORT)) socket.listen(1) conn, addr = socket.accept() print '\033[46m\033[34m\033[1mBienvenido al File Sender v.0.02 hecho en Python. Este programa permite enviar archivos a traves de tu maquina\033[0m' ANSI_RED = '\033[31m' ANSI_BLUE = '\033[34m' ESCAPEANSI = '\033[0m' def seleccion_path(): PATH = raw_input('\033[34m\033[1mSelect the Path (./ by default)').strip('n') if PATH == '': PATH = os.getcwd() print PATH, ESCAPEANSI acepta_path = raw_input('\033[34m\033[1mSi o No (S/N)').lower().strip(' ') if acepta_path == 's' or acepta_path == 'si': return PATH else: seleccion_path() def filesDir(path): files = os.listdir(PATH) for fl in files: i = int(files.index(fl))+1 print ANSI_RED + str(i)+ ')' + fl return files PATH = seleccion_path() print 'el PATH seleccionado es:', PATH + '\n' filesDir(PATH) fileSelected = int(raw_input(ANSI_BLUE + 'Select a file with the number').strip(' ').lower()) print PATH + filesDir(PATH)[fileSelected-1] filepath = PATH + filesDir(PATH)[fileSelected-1] #envia nombre del file conn.send(filepath) qLines = len(open(PATH + filesDir(PATH)[fileSelected-1], 'rb').readlines()) fileToSend = open(filepath, 'rb') while True: data = fileToSend.readline() if data: conn.send(data) else: break fileToSend.close() conn.sendall('') conn.close() print '\033[43m File sent' #Finaliza el programa y deja los codigos ANSI cerrados print ESCAPEANSI exit() 

Client side:

 import os import socket PORT = 8080 HOST = 'localhost' nombrearchivo = raw_input('define a name with its extension').strip(' ') socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) socket.connect((HOST, PORT)) filename = socket.recv(1024) fname = open('./'+nombrearchivo, 'wb') while True: strng = socket.recv(1024) if strng: print strng fname.write(strng) else: fname.close() break socket.close() print 'Data received correctly' exit() 
+2
source

Your problem is that you open the file, read all the lines (using readlines ), and then try to read the file again without closing it.

I share @ T_12's question about why you want to send the last line of the file first. But provided that you need to do this, here is what you need:

Replace this part of the severside code (since I don’t see where you defined cpfileToSend , I assume it should have been fileToSend )

 fileToSend = open(PATH + filesDir(PATH)[fileSelected-1], 'rb') qLines = len(open(PATH + filesDir(PATH)[fileSelected-1], 'rb').readlines()) finalLine = cpfileToSend.readlines()[qLines-1] conn.send(finalLine) while True: data = conn.sendall(fileToSend.readline()) conf = conn.recv(1024) print conf if conf == 'OK': conn.close() fileToSend.close() break 

with this

 filepath = PATH + filesDir(PATH)[fileSelected-1] fileToSend = open(filepath, 'rb') qLines = len(open(PATH + filesDir(PATH)[fileSelected-1], 'rb').readlines()) finalLine = fileToSend.readlines()[qLines-1] conn.send(finalLine) fileToSend.close() fileToSend = open(filepath, 'rb') while True: data = conn.sendall(fileToSend.readline()) conf = conn.recv(1024) print conf if conf == 'OK': conn.close() fileToSend.close() break 

Hope this helps

+1
source

All Articles