溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python模擬FTP文件服務器的操作方法

發(fā)布時間:2020-10-13 16:33:19 來源:腳本之家 閱讀:183 作者:Rookie_Max 欄目:開發(fā)技術(shù)

分為服務端和客戶端,要求可以有多個客戶端同時操作。

客戶端可以查看服務器文件庫中有什么文件。
客戶端可以從文件庫中下載文件到本地。
客戶端可以上傳一個本地文件到文件庫。
使用print在客戶端打印命令輸入提示,引導操作

服務端

# 導入相關(guān)模塊
from socket import *
from multiprocessing import Process
import signal, os, time
# 綁定IP地址
IP = "127.0.0.1"
# 綁定端口
PORT = 8888
ADDR = (IP, PORT)
# 綁定服務器的指定目錄
DIR = "/home/max/ftp"
# 處理查看文件請求
def browse(c):
 # 列表方式查看文件
 list = os.listdir("%s" % DIR)
 # 按通信協(xié)議格式組織數(shù)據(jù)
 msg = "B " + ";".join(list)
 # 發(fā)送到客戶端
 c.send(msg.encode())
# 處理客戶端下載文件請求
def download(c, file):
 # 判斷文件是否存在且是否是文件
 if file in os.listdir(DIR) and os.path.isfile("%s/%s" % (DIR, file)):
  # 打開文件
  f = open("%s/%s" % (DIR, file), "rb")
  # 發(fā)送下載代碼,告知客戶端進入"D"
  c.send(("D %s " % file).encode())
  # 等待客戶端先進入"D"模式下的recv阻塞函數(shù)
  time.sleep(0.1)
  # 循環(huán)發(fā)送文件
  while True:
   data = f.read(1000)
   if not data:
    # 設置間隔,等待文件傳輸完整
    time.sleep(0.1)
    # 約定的信息讓客戶端退出接收循環(huán)
    c.send(b"finished")
    break
   c.send(data)
  f.close()
 # 否則按協(xié)議格式發(fā)送錯誤代碼
 else:
  c.send(b"D fileerror ")
# 處理客戶端上傳文件請求
def upload(c, file):
 # 創(chuàng)建文件
 f = open("%s/%s" % (DIR, file), "wb")
 # 循環(huán)接收文件
 while True:
  data = c.recv(1024)
  # 收到約定的信息退出循環(huán)
  if data == b"finished":
   break
  f.write(data)
 f.close()
# 處理客戶端退出請求
def login_out(c):
 # 按協(xié)議格式組織信息
 msg = "O closed "
 # 發(fā)給客戶端的recv_msg進程
 c.send(msg.encode())
def deal(c):
 # 發(fā)送代碼告知客戶端連接成功
 c.send(b"K ")
 while True:
  # 循環(huán)接收客戶端請求,約定通信協(xié)議為"* ** ****"格式
  msg = c.recv(1024)
  # 如果客戶端崩了,解除該子進程
  if not msg:
   break
  # 解析請求
  req = msg.decode().split(" ", 2)
  # 處理查看文件請求,跳入browse函數(shù)
  if req[0] == "B":
   browse(c)
  # 處理客戶端下載文件請求,跳入download函數(shù)
  elif req[0] == "D":
   download(c, req[1])
  # 處理客戶端上傳文件請求,跳入upload函數(shù)
  elif req[0] == "U":
   upload(c, req[1])
  # 處理客戶端退出請求,跳入login_out函數(shù)
  elif req[0] == "O":
   login_out(c)
   # 跳出循環(huán),結(jié)束子進程
   break
# 主程序,父進程用于接收客戶端請求并循環(huán)創(chuàng)建子進程,子程序處理請求
def main():
 # 創(chuàng)建tcp套接字
 s = socket()
 # 綁定服務器地址
 s.bind(ADDR)
 # 設置監(jiān)聽套接字
 s.listen()
 # 處理僵尸進程
 signal.signal(signal.SIGCHLD, signal.SIG_IGN)
 while True:
  # 連接客戶端
  c, addr = s.accept()
  # 創(chuàng)建子進程,用以處理客戶端請求,跳入deal函數(shù)
  p = Process(target=deal, args=(c,))
  # 子程序開始執(zhí)行
  p.start()
if __name__ == '__main__':
 main()

客戶端

# 導入相關(guān)模塊
from socket import *
import os, sys, time
# 綁定服務端IP地址
IP = "127.0.0.1"
# 綁定服務端端口
PORT = 8888
ADDR = (IP, PORT)
# 收到約定的信息退出循環(huán)
# 發(fā)送消息進程
def send_msg(s):
 # 等待接收進程先運行到"K"分支
 time.sleep(0.1)
 while True:
  try:
   # 輸入指令
   data = input(">>>")
  except:
   # 客戶端錯誤,向服務端發(fā)送O
   data = "O"
  if data == "B": # 查看目錄
   msg = "B "
   s.send(msg.encode())
  elif data == "D": # 下載文件
   # 輸入想要下載的文件
   want = input("download ? file:")
   msg = "D %s " % want
   s.send(msg.encode())
  elif data == "U": # 上傳文件
   file = input("upload ? file:")
   # 判斷文件是否在客戶端文件所在的目錄且是文件
   if file in os.listdir(os.getcwd()) and os.path.isfile("%s/%s" % (os.getcwd(), file)):
    msg = "U %s " % file
    s.send(msg.encode())
    f = open("%s" % file, "rb")
    # 等待服務端進入upload的recv阻塞函數(shù)
    time.sleep(0.1)
    while True:
     data = f.read(1000)
     if not data:
      # 設置間隔,等待文件傳輸完整
      time.sleep(0.1)
      # 約定的信息讓客戶端退出接收循環(huán)
      s.send(b"finished")
      break
     s.send(data)
    f.close()
    print("upload succussfully")
   # 否則按協(xié)議格式顯示錯誤代碼
   else:
    print("file not exist\ninput BDUO to forward\n", end="")
  elif data == "O": # 斷開連接
   msg = "O "
   s.send(msg.encode())
   sys.exit()
  # 指令錯誤
  else:
   print("input error")

# 接收消息進程
def recv_msg(s):
 while True:
  data = s.recv(1024)
  # 解析數(shù)據(jù)
  msg = data.decode().split(" ", 2)
  if msg[0] == "K": # 登錄成功反饋
   print(
    "login in successfully\ninput B to browse,D to download,U to upload,O to login out")
  elif msg[0] == "B": # 查看目錄反饋
   # 如果文件庫不為空
   if msg[2]:
    print("files:", msg[2], "\n>>>", end="")
   else:
    print("files: no files", "\n>>>", end="")
  elif msg[0] == "D":
   # 服務端文件不存在
   if msg[1] == "fileerror":
    print("file not exist\ninput BDUO to forward\n>>>", end="")
    continue
   # 服務端文件存在
   else:
    f = open("%s" % msg[1], "wb")
    while True:
     data = s.recv(1024)
     # 收到約定的信息退出循環(huán)
     if data == b"finished":
      break
     f.write(data)
    f.close()
    print("download successfully\n>>>", end="")
  elif msg[0] == "O": # 收到來自發(fā)送消息進程發(fā)送到服務端的斷開請求
   # 進程退出并打印提示
   sys.exit("login out successfully")

# 主程序
def main():
 # 創(chuàng)建tcp套接字
 s = socket()
 # 連接服務端
 s.connect(ADDR)
 # 創(chuàng)建多進程,子進程用于發(fā)送消息,父進程用于接收消息
 pid = os.fork()
 if pid < 0:
  print("system error")
 # 子進程
 elif pid == 0:
  send_msg(s)
 # 父進程
 else:
  recv_msg(s)
if __name__ == '__main__':
 main()

總結(jié)

以上所述是小編給大家介紹的Python_模擬FTP文件服務器的操作方法,希望對大家有所幫助,也非常感謝大家對億速云網(wǎng)站的支持!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI