使用Python进行Socket文件传输
我正在用Python通过套接字(sockets)构建一个简单的文件传输功能。可是我卡住了,似乎无法发送文件的任何部分。
根据一些建议,我尝试发送文件的最后一行,这样我就能知道什么时候可以结束连接。
但是问题是,一旦我发送了第一个数据包,客户端就再也收不到后面的内容了。
下面是我的代码(服务器端):
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()
这是客户端的代码:
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()
2 个回答
1
你的问题出在你打开文件后,使用 readlines
读取了所有的行,然后又试图在不关闭文件的情况下再次读取文件。
我也和 @T_12 一样好奇,为什么你想先发送文件的最后一行。不过假设你确实有这样的需求,这里有个解决办法:
把你服务器端代码中的这一部分替换掉(因为我没看到你定义 cpfileToSend
的地方,我猜它应该是 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
换成这个
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
希望这能帮到你
2
最后我终于搞定了。问题出在socket.recv()上。我之前请求应用程序执行好几行代码,但服务器没有发送任何数据。客户端在那行代码之后就没继续执行,因为它在等着接收数据,以便继续运行后面的代码。
我调整了一下代码来解决这个问题,现在运行得很好。
我真心喜欢Python :)
服务器端:
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()
客户端:
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()