通过python中的TCP套接字在客户端-服务器之间发送文件? [英] Sending files between client - server through TCP socket in python?
问题描述
我正在尝试通过TCP套接字发送和接收文件。当用户键入输入abc.txt
时,应将abc.txt复制到服务器。
当用户键入时获取定义。 txt
,def.txt应该下载到用户计算机。 (实际上,我还必须实现2种方法- ls
列出客户端目录中的所有文件,而 lls
列出所有方法服务器中的文件,但我还没有完成。)
I'm trying to send and receive files through a TCP socket. When user types put abc.txt
, abc.txt should be copied to the server.
When user types get def.txt
, def.txt should be downloaded to the user computer. (Actually I have to implement 2 more methods - ls
to list all files in the client directory and lls
to list all files in the server, but I haven't done it yet.)
这是代码
服务器
import socket
import sys
HOST = 'localhost'
PORT = 3820
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind((HOST, PORT))
socket.listen(1)
while (1):
conn, addr = socket.accept()
print 'New client connected ..'
reqCommand = conn.recv(1024)
print 'Client> %s' %(reqCommand)
if (reqCommand == 'quit'):
break
#elif (reqCommand == lls):
#list file in server directory
else:
string = reqCommand.split(' ', 1) #in case of 'put' and 'get' method
reqFile = string[1]
if (string[0] == 'put'):
with open(reqFile, 'wb') as file_to_write:
while True:
data = conn.recv(1024)
if not data:
break
file_to_write.write(data)
file_to_write.close()
break
print 'Receive Successful'
elif (string[0] == 'get'):
with open(reqFile, 'rb') as file_to_send:
for data in file_to_send:
conn.sendall(data)
print 'Send Successful'
conn.close()
socket.close()
客户
import socket
import sys
HOST = 'localhost' #server name goes in here
PORT = 3820
def put(commandName):
socket.send(commandName)
string = commandName.split(' ', 1)
inputFile = string[1]
with open(inputFile, 'rb') as file_to_send:
for data in file_to_send:
socket.sendall(data)
print 'PUT Successful'
return
def get(commandName):
socket.send(commandName)
string = commandName.split(' ', 1)
inputFile = string[1]
with open(inputFile, 'wb') as file_to_write:
while True:
data = socket.recv(1024)
#print data
if not data:
break
print data
file_to_write.write(data)
file_to_write.close()
break
print 'GET Successful'
return
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((HOST,PORT))
msg = raw_input('Enter your name: ')
while(1):
print 'Instruction'
print '"put [filename]" to send the file the server '
print '"get [filename]" to download the file from the server '
print '"ls" to list all files in this directory'
print '"lls" to list all files in the server'
print '"quit" to exit'
sys.stdout.write ('%s> ' %msg)
inputCommand = sys.stdin.readline().strip()
if (inputCommand == 'quit'):
socket.send('quit')
break
# elif (inputCommand == 'ls')
# elif (inputCommand == 'lls')
else:
string = inputCommand.split(' ', 1)
if (string[0] == 'put'):
put(inputCommand)
elif (string[0] == 'get'):
get(inputCommand)
socket.close()
有些问题我无法解决。
There are several problems that I couldn't fix.
- 该程序仅在首次运行时正确运行( put和
get方法)。之后,无法将来自客户端的所有命令发送给服务器
。 - get方法不适用于图像/照片文件。 li>
- The program run correctly only on the first time (both 'put' and 'get' method). After that, All commands from the client can't be sent to the server.
- The 'get' method doesn't work for an image/photo file.
推荐答案
出现第一个问题是因为在处理了一个命令后,服务器正在关闭连接。
First problem is occurring because after handling one command, server is closing the connection.
conn.close()
发生第二个问题,因为您没有从客户端的套接字读取所有数据。在while循环结束时,您有一个 break语句,由于该语句,客户机在读取1024个字节后才关闭套接字。而当服务器尝试在此关闭的套接字上发送数据时,则会在服务器端导致错误。
Second problem is occurring because you are not reading all the data from the socket in client. At the end of while loop you have a "break" statement, due to which client is closing the socket just after reading 1024 bytes. And when server tries to send data on this close socket, its results in error on the server side.
while True:
data = socket1.recv(1024)
# print data
if not data:
break
# print data
file_to_write.write(data)
file_to_write.close()
break
有两种方法可以解决第一个问题。
There are two ways to fix this first issue.
- 更改客户端,以便为每个命令创建一个新的连接&将命令发送到服务器。
- 更改服务器以通过同一连接处理多个命令。
以下代码是更改后的客户端,以演示解决第一个问题的第一种方法。
Following code is the changed client to demonstrate the first way to fix the first issue. It also fixes the second issue.
import socket
import sys
HOST = 'localhost' # server name goes in here
PORT = 3820
def put(commandName):
socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket1.connect((HOST, PORT))
socket1.send(commandName)
string = commandName.split(' ', 1)
inputFile = string[1]
with open(inputFile, 'rb') as file_to_send:
for data in file_to_send:
socket1.sendall(data)
print 'PUT Successful'
socket1.close()
return
def get(commandName):
socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket1.connect((HOST, PORT))
socket1.send(commandName)
string = commandName.split(' ', 1)
inputFile = string[1]
with open(inputFile, 'wb') as file_to_write:
while True:
data = socket1.recv(1024)
# print data
if not data:
break
# print data
file_to_write.write(data)
file_to_write.close()
print 'GET Successful'
socket1.close()
return
msg = raw_input('Enter your name: ')
while(1):
print 'Instruction'
print '"put [filename]" to send the file the server '
print '"get [filename]" to download the file from the server '
print '"ls" to list all files in this directory'
print '"lls" to list all files in the server'
print '"quit" to exit'
sys.stdout.write('%s> ' % msg)
inputCommand = sys.stdin.readline().strip()
if (inputCommand == 'quit'):
socket.send('quit')
break
# elif (inputCommand == 'ls')
# elif (inputCommand == 'lls')
else:
string = inputCommand.split(' ', 1)
if (string[0] == 'put'):
put(inputCommand)
elif (string[0] == 'get'):
get(inputCommand)
这篇关于通过python中的TCP套接字在客户端-服务器之间发送文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!