我正在寻找一些有关我的python套接字编程的帮助。
目标:将文件从客户端上传到服务器。我当前的设置涉及两个虚拟机,分别是服务器和客户端,分别位于其中的.py文件。 server.py和client.py。我遇到的问题是,当我选择上载选项时,输出显示为“文件上载...。文件成功上载”,但是当我在服务器端查看时,该文件不存在-也没有我收到一个错误。当我发送文件上传时,服务器显示它已接收到连接。我目前所拥有的是……任何帮助将不胜感激。
Server.py
import config, protocol
import os
from socket import *
import threading
import time
import sys
class server():
# Constructor: load the server information from config file
def __init__(self):
self.port, self.path, self.path2 = config.config().readServerConfig()
# function to receive file data from client
def receiveFile(self, serverSocket, fileName):
serverSocket.connect()
serverSocket.send(protocol.prepareMsg(protocol.HEAD_UPLOAD, fileName))
with open(fileName, 'wb') as f:
print('file incoming...')
while True:
print('receiving data...')
data = serverSocket.recv(1024)
if not data:
break
f.write(data)
print(fileName + " has been Received!")
serverSocket.close()
# Main function of server, start the file sharing service
def start(self):
serverPort=self.port
serverSocket=socket(AF_INET,SOCK_STREAM)
serverSocket.bind(('',serverPort))
serverSocket.listen(20)
print('The server is ready to receive')
while True:
connectionSocket, addr = serverSocket.accept()
print("**Conn. to ", addr)
dataRec = connectionSocket.recv(1024)
header,msg= protocol.decodeMsg(dataRec.decode()) # get client's info, parse it to header and content
# Main logic of the program, send different content to client according to client's requests
if(header== protocol.HEAD_REQUEST):
self.listFile(connectionSocket)
elif(header == protocol.HEAD_DOWNLOAD):
self.sendFile(connectionSocket, self.path+"/"+msg)
elif(header == protocol.HEAD_UPLOAD):
self.receiveFile(connectionSocket, self.path2+"/"+msg)
else:
connectionSocket.send(protocol.prepareMsg(protocol.HEAD_ERROR, "Invalid Message"))
connectionSocket.close()
def main():
s=server()
s.start()
main()
Client.py
import config, protocol
from socket import *
import threading
import time
import os
import sys
class client:
fileList=[] # list to store the file information
uploadFileList = []
#Constructor: load client configuration from config file
def __init__(self):
self.serverName, self.serverPort, self.clientPort, self.downloadPath, self.uploadPath = config.config().readClientConfig()
# Function to produce user menu
def printMenu(self):
print("Welcome to simple file sharing system!")
print("Please select operations from menu")
print("--------------------------------------")
print("3. Upload File")
print("5. Quit")
# Function to get user selection from the menu
def getUserSelection(self):
ans=0
# only accept option 1-4
while ans>5 or ans<1:
self.printMenu()
try:
ans=int(input())
except:
ans=0
if (ans<=5) and (ans>=1):
return ans
print("Invalid Option")
# Build connection to server
def connect(self):
serverName = self.serverName
serverPort = self.serverPort
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((serverName,serverPort))
return clientSocket
def getUploadFileList(self):
self.uploadFileList = os.listdir(self.uploadPath)
def printUploadFileList(self):
count = 0
for f in self.uploadFileList:
count += 1
print('{:<3d}{}'.format(count, f))
def selectUploadFile(self):
if (len(self.uploadFileList)==0):
self.getUploadFileList()
ans=-1
while ans<0 or ans>len(self.uploadFileList)+1:
self.printUploadFileList()
print("Please select the file you want to upload from the list (enter the number of files):")
try:
ans=int(input())
except:
ans=-1
if (ans>0) and (ans<len(self.uploadFileList)+1):
return self.uploadFileList[ans-1]
print("Invalid number")
def uploadFile(self, fileName):
mySocket=self.connect()
mySocket.send(protocol.prepareMsg(protocol.HEAD_UPLOAD, fileName))
f = open(fileName, 'rb')
l = f.read(1024) # each time we only send 1024 bytes of data
while (l):
print('File uploading...')
mySocket.sendall(l)
l = f.read(1024)
f.close()
print("File Uploaded Successfully!")
# Main logic of the client, start the client application
def start(self):
opt=0
while opt!=5:
opt=self.getUserSelection()
if opt==3:
self.uploadFile(self.selectUploadFile())
else:
pass
def main():
c=client()
c.start()
main()
我已经在协议文件中定义了我拥有的模块...
Protocol.py
HEAD_LIST='LST'
HEAD_REQUEST='REQ'
HEAD_DOWNLOAD='DLD'
HEAD_UPLOAD='ULD'
HEAD_FILE='FIL'
HEAD_ERROR='ERR'
# we prepare the message that are sent between server and client as the header + content
def prepareMsg(header, msg):
return (header+msg).encode()
def prepareFileList(header,fList):
'''
function to prepare file list to msg
'''
msg=header
for i in range(len(fList)):
if (i==len(fList)-1):
msg+=fList[i]
else:
msg+=fList[i]+','
return msg.encode()
# Decode the received message, the first three letters are used as protocol header
def decodeMsg(msg):
if (len(msg)<=3):
return HEAD_ERROR, 'EMPTY MESSAGE'
else:
return msg[0:3],msg[3:len(msg)]
我还定义了我的配置文件,如下所示...
Config.py
class config:
#define header
server_port='SERVER_PORT'
path="PATH"
path2="PATH2"
server="SERVER"
client_port="CLIENT_PORT"
download="DOWNLOAD"
upload="UPLOAD"
serverConfig="server.config"
clientConfig="client.config"
def __init__(self):
pass
def readServerConfig(self):
try:
with open(self.serverConfig,'r') as f:
serPort=0
sharePath=""
sharePath2=""
for l in f:
sub=l.strip().split("=")
if(sub[0]==self.server_port):
serPort=int(sub[1])
elif(sub[0]==self.path):
sharePath=sub[1]
elif (sub[0] == self.path2):
sharePath2 = sub[1]
else:
pass
return serPort, sharePath, sharePath2
except:
print(Exception.message())
def readClientConfig(self):
'''
This function read client configuration file, return four values
@return: serverName
@return: serverPort
@return: clientPort
@return: downloadPath
'''
try:
with open(self.clientConfig,'r') as f:
serPort=0
serName=""
clientPort=0
downPath=""
upPath=""
for l in f:
sub=l.strip().split("=")
if(sub[0]==self.server_port):
serPort=int(sub[1])
elif(sub[0]==self.server):
serName=sub[1]
elif(sub[0]==self.client_port):
clientPort=sub[1]
elif(sub[0]==self.download):
downPath=sub[1]
elif(sub[0]==self.upload):
upPath=sub[1]
else:
pass
return serName, serPort, clientPort, downPath, upPath
except:
print(Exception.message())
# The function to test the configuration class
def test():
conf=config()
client=conf.readClientConfig()
server=conf.readServerConfig()
print(client)
print(server)
上面的代码将返回文件列表,我可以选择我要上传的文件,并且代码将声明其完整,但是我无法在服务器上找到文件。我在两台计算机的目录路径中都设置了测试文件。另外,我的server.config和client.config文件设置为:
server.config
SERVER_PORT=12007
PATH=/root/serverFiles
PATH2=/root/files
client.config
SERVER=192.168.10.1
SERVER_PORT=12007
CLIENT_PORT=12006
DOWNLOAD=/root/Downloads
UPLOAD=/root/Upload
答案 0 :(得分:1)
您的uploadFile()
方法将connect()
发送到服务器,然后sendall()
发送文件内容(以1024字节为块)。
您的服务器将接收前1024个字节(即文件 内容的前1024个字节),并根据协议进行解释,查看文件的前三个字节 文件 内容。但是,客户端永远不会像服务器期望的那样发送protocol.HEAD_UPLOAD
。
(顺便说一句,我真的很推荐您PEP8代码,并避免使用*
导入。它使代码更易于阅读,从而对您有所帮助。)