1. 程式人生 > >python網路程式設計 socketserver和ftp

python網路程式設計 socketserver和ftp

socketserver 是 python 中提供的一個可以用於面向物件服務端開發的一個高階模組,封裝了底層 socket 的大量操作實現,通過提供面向物件的操作方式簡化程式開發。 在這裡插入圖片描述

TCP程式設計:

伺服器端
# 匯入依賴的模組
import socketserver
# 定義服務主機資訊
HOST = '192.168.1.107'
PORT = 8080
ADDRESS = (HOST, PORT)
BUFFER = 1024
# 自定義處理類
class MyRequestHandler(socketserver.StreamRequestHandler):
# 定義處理方法
	def handle(self):
		# 通過 client_address 屬性檢視連線進來的伺服器
		print("連線上的伺服器: %s" % str(self.client_address))
		# 接收客戶端傳送的資料
		msg = self.request.recv(BUFFER)
		print("客戶端發過來訊息: %s" % msg.decode("UTF-8"))
		# 給客戶端返回接收資訊
		self.request.sendall("已經成功接收您傳送的訊息".encode("UTF-8"))
# 程式從主執行緒直接執行
if __name__ == "__main__":
	# 建立服務端物件,指定處理類,並監聽 8888 埠
	server = socketserver.TCPServer(ADDRESS, MyRequestHandler)
	print("server is starting, waiting for connect.....")
	# 啟動服務端程式
	server.serve_forever()

客戶端的操作也比較簡單,唯一需要注意的是:使用 TCPServer 構建的 TCP 服務端在和客戶端進行資料通訊的過程中,每一次的資料通訊都會使用一個新的套接字物件,所以客戶端程式需要改造~每次和伺服器進行資料互動時都需要建立一個新套接字。

# 匯入依賴的模組
import socket
# 定義主機資訊
HOST = '192.168.1.107'
PORT = 8080
ADDRESS = (HOST, PORT)
# 訊息迴圈
while True:
	# 建立一個 TCP 套接字物件AUTHOR:大牧莫邪 VERSION: 1.0 DATE:2018-08-15
	20 / 25
	client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
	# 連線目標主機
	client.connect(ADDRESS)
	# 訊息收發
	msg = input("enter message:")
	client.send(msg.encode("utf-8"))
	if msg == "BYE":
	break
	info = client.recv(1024)
	print(info)
# 關閉套接字
client.close()

UDP程式設計

服務端開發
# 引入依賴的模組
from socketserver import (UDPServer as UDP, DatagramRequestHandler as DRH)
# 伺服器描述資訊
HOST = '192.168.1.107'
PORT = 8888
ADDRESS = (HOST, PORT)
# 自定義訊息處理類
class MyRequestHandler(DRH):
	# 訊息處理函式
	def handle(self):
		print('客戶端接入成功,開始收發訊息: ', self.client_address)
		# 接受訊息
		msg = self.rfile.readline()
		print(msg.decode('utf-8'))
		# 傳送訊息
		self.wfile.write("my name is server,伺服器".encode("utf-8"))
if __name__ == "__main__":
# 建立 UDP 伺服器
udp_server = UDP(ADDRESS, MyRequestHandler)
print("server is starting...")
# 啟動 UDP 伺服器
udp_server.serve_forever()

客戶端開發
import socket
HOST = '192.168.1.107'
PORT = 8888
ADDRESS = (HOST, PORT)
while True:
	client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
	# 傳送訊息
	info = input("enter message:")
	client.sendto(info.encode("utf-8"), ADDRESS)
	# 接受訊息
	msg, addr = client.recvfrom(1024)
	print(addr, " say : " , msg)
	client.close()

FTP客戶端程式開發

虛擬碼
from ftplib import FTP
ftp = FTP(“ftp.server.com”)
ftp.login(‘account’, ‘password’)
# 資料互動
ftp.quit()

FTP型別常見屬性方法 在這裡插入圖片描述

客戶端程式開發
# 引入需要的模組
import ftplib, socket
# 定義 FTP 主機資訊
HOST = '192.168.1.108'
DIRN = '/home/damu/ftpwork/'
FILE = 'my_demo.tar.gz'
class FtpClient:
'''自定義 FTP 客戶端型別'''
def __init__(self, host, username, password):
	'''
	初始化方法
	:param host:目標主機
	:param directory:目標主機目錄
	:param files:要下載的檔案
	:param username:登入賬號
	:param password:登入密碼
	'''
	self.host = host
	self.username = username
	self.password = password
	def ftp_dowload(self, directory, file):
	'''下載檔案主要方法'''
	self.directory = directory
	self.file = file
	self.__ftp_connect()
	self.__ftp_login()
	self.__ftp_cwd()
	self.__ftp_download()
	self.__ftp_quit()
def __ftp_connect(self):
	'''連線伺服器的方法'''
	try:
		self.ftp = ftplib.FTP(self.host)
		except (socket.error, socket.gaierror) as e:
		print("目標主機不可訪問: ", self.host)
	else:
		print("主機連線成功", self.host)
def __ftp_login(self):
	'''登入 FTP 伺服器的方法'''
	try:
		self.ftp.login()
		except ftplib.error_perm:
		print("目標主機不能匿名登入,使用賬號密碼登入")
	try:
		self.ftp.login(user=self.username, passwd=self.password)
		except:
		print("賬號或者密碼有誤")
	else:
		print("登入成功")
def __ftp_cwd(self):
	'''修改工作目錄的方法'''
	try
		self.ftp.cwd(self.directory)
	except ftplib.error_perm as e:
		print("路徑修改失敗,沒有許可權", self.directory)
	else:
		print("路徑修改完成")
def __ftp_download(self):
	'''下載檔案核心方法'''
	try:
		self.ftp.retrbinary('RETR {}'.format(self.file), open(self.file, 'wb').write)
	except ftplib.error_perm as e:
		print("檔案下載失敗...")
	else:
		print("檔案下載完成")
def __ftp_quit(self):
	'''退出 FTP 客戶端'''
	self.ftp.quit()
	print('程式退出...')
if __name__ == "__main__":
	# 建立 FTP 客戶端物件
	ftp = FtpClient(HOST, 'damu', '123456')
	# 下載指定路徑下的檔案
	ftp.ftp_dowload(DIRN, FILE)