在 python 中通过 TCP 套接字在客户端-服务器之间发送文件?
Sending files between client - server through TCP socket in python?
我正在尝试通过 TCP 套接字发送和接收文件。当用户键入 put abc.txt
时,应将 abc.txt 复制到服务器。
当用户键入 get def.txt
时,def.txt 应下载到用户计算机。 (实际上我还必须实现 2 个方法 - ls
列出客户端目录中的所有文件,lls
列出服务器中的所有文件,但我还没有实现。)
这是代码
服务器
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()
有几个问题我无法解决。
- 程序 运行 仅在第一次正确('put' 和
'get' 方法)。之后,客户端的所有命令都不能
发送到服务器。
- 'get' 方法不适用于 image/photo 文件。
出现第一个问题是因为在处理一个命令后,服务器正在关闭连接。
conn.close()
出现第二个问题是因为您没有从客户端的套接字中读取所有数据。在 while 循环结束时,您有一个 "break" 语句,由于客户端在读取 1024 字节后立即关闭套接字。当服务器试图在这个关闭的套接字上发送数据时,它会导致服务器端出错。
while True:
data = socket1.recv(1024)
# print data
if not data:
break
# print data
file_to_write.write(data)
file_to_write.close()
break
有两种方法可以解决第一个问题。
- 更改客户端,以便为每个命令创建一个新连接并将命令发送到服务器。
- 更改服务器以通过同一连接处理多个命令。
以下代码是修改后的客户端,用于演示第一种方法修复第一个问题。它还修复了第二个问题。
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)
我正在尝试通过 TCP 套接字发送和接收文件。当用户键入 put abc.txt
时,应将 abc.txt 复制到服务器。
当用户键入 get def.txt
时,def.txt 应下载到用户计算机。 (实际上我还必须实现 2 个方法 - ls
列出客户端目录中的所有文件,lls
列出服务器中的所有文件,但我还没有实现。)
这是代码
服务器
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()
有几个问题我无法解决。
- 程序 运行 仅在第一次正确('put' 和 'get' 方法)。之后,客户端的所有命令都不能 发送到服务器。
- 'get' 方法不适用于 image/photo 文件。
出现第一个问题是因为在处理一个命令后,服务器正在关闭连接。
conn.close()
出现第二个问题是因为您没有从客户端的套接字中读取所有数据。在 while 循环结束时,您有一个 "break" 语句,由于客户端在读取 1024 字节后立即关闭套接字。当服务器试图在这个关闭的套接字上发送数据时,它会导致服务器端出错。
while True:
data = socket1.recv(1024)
# print data
if not data:
break
# print data
file_to_write.write(data)
file_to_write.close()
break
有两种方法可以解决第一个问题。
- 更改客户端,以便为每个命令创建一个新连接并将命令发送到服务器。
- 更改服务器以通过同一连接处理多个命令。
以下代码是修改后的客户端,用于演示第一种方法修复第一个问题。它还修复了第二个问题。
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)