NO.8:自学python之路------并行socket网络编程
摘要
一到放假就雜事很多,這次的作業(yè)比較復雜,做了一個周,進度又拖了。不過結(jié)果還不錯。
正文
粘包
在上一節(jié)中,如果連續(xù)發(fā)送過多數(shù)據(jù),就可能發(fā)生粘包。粘包就是兩次發(fā)送的數(shù)據(jù)粘在一起被接收,損壞了數(shù)據(jù)的完整性。解決方法有兩種。
方案一:
在發(fā)送多個數(shù)據(jù)之間添加接收確認。這樣在完成一次發(fā)送以后只有接收到另一端的確認以后才會開始新的發(fā)送,避免了粘包的發(fā)生。
方案二:
首先將發(fā)送數(shù)據(jù)的大小發(fā)送給另一端,另一端根據(jù)數(shù)據(jù)的大小接收。一次接收一次發(fā)送的數(shù)據(jù)量,這樣也就避免了數(shù)據(jù)的粘包。例子。
#方案1 #server f = open(path, 'wb') for i in f:server.socket.send(i) f.close() server.socket.recv(1024) server.socket.send(b'發(fā)送完畢') #client recv_data = '' while True:data = client.socket.recv(1024)if not data:breakrecv_data += data client.socket.send(b'recv over') other_data = client.socket.recv(1024) #方案2 #server size = os.path.getsize(path) server.socket.send(size.encode()) server.socket.recv(1024) f = open(path, 'wb') for i in f:server.socket.send(i) f.close() server.socket.send(b'發(fā)送完畢') #client size = client.socket.recv(1024) client.socket.send(b'start') recv_data = '' recv_size = 0 while recv_size < size:if size - recv_size < 1024:single_size = size - recv_sizeelse:single_size = 1024data = client.socket.recv(single_size)recv_size += len(data)recv_data += data other_data = client.socket.recv(1024) View CodeFTP
一個簡單的FTP過程主要包含以下幾個步驟。
1.讀取文件名
2.檢測文件是否存在
3.打開文件
4.檢測文件大小,文件名
5.發(fā)送文件大小 md5值給客戶端
6.等待客戶端確認
7.開始邊讀取數(shù)據(jù)邊發(fā)送數(shù)據(jù)
8.md5確認
具體例子。
服務器
# 服務器端 import socket import os import hashlibserver = socket.socket() server.bind(('localhost', 9999)) server.listen()while True:conn, addr = server.accept()print('new conn:', addr)while True:data = conn.recv(1024)data = data.decode()if not data:print('客戶端已斷開')breakcmd, filename = data.split()print(filename)if os.path.isfile(filename):f = open(filename, 'rb')m = hashlib.md5()file_size = os.stat(filename).st_sizeprint(file_size)conn.send(str(file_size).encode('utf-8'))conn.recv(1024)for line in f:m.update(line)conn.send(line)print('md5:', m.hexdigest())f.close()conn.send(m.hexdigest().encode('utf-8')) View Code客戶端
# 客戶端 import socket import hashlibclient = socket.socket() client.connect(('localhost', 9999))while True:cmd = input('>>').strip()if len(cmd) == 0:continueif cmd.startswith('get'):client.send(cmd.encode('utf-8'))cmd_res_size = client.recv(1024) # 接收長度print('文件大小 %s' % (cmd_res_size.decode()))client.send('準備完畢,開始發(fā)送數(shù)據(jù)'.encode('utf-8'))recv_size = 0file_name = cmd.split()[1]f = open(file_name + '.new', 'wb')m = hashlib.md5()while recv_size < int(cmd_res_size.decode()):if int(cmd_res_size.decode()) - recv_size > 1024:size = 1024else:size = int(cmd_res_size.decode()) - recv_sizedata = client.recv(size)recv_size += len(data) # 讀取每次接收的數(shù)據(jù) f.write(data)m.update(data)#print(recv_size)else:file_md5 = m.hexdigest()print('文件接收完畢', recv_size)f.close()recv_md5 = client.recv(1024)print(file_md5, recv_md5.decode()) client.close() View CodeSocketServer
SocketServer是Python的一個包,它在socket的基礎上封裝,可以更加簡單的完成并發(fā)處理。
socketserver.TCPServer 繼承BaseServer,完成TCP
socketserver.UDPServer 繼承TCPServer,完成UDP
socketserver.UnixStreamServer?繼承TCPServer,完成Unix的TCP
socketserver.UnixDatagramServer?繼承UDPServer,完成Unix的UDP
使用socketserver的步驟:
1.創(chuàng)建一個請求處理類,并且這個類要繼承BaseRequestHandler,并且需要重寫父類中的Handle()方法。
2.實例化一個Server類,并且傳遞Server ip和1中創(chuàng)建的請求處理類給它。
3.server.handle_request()只處理一個請求 server.server_forever()處理多個請求,永久執(zhí)行。
4.調(diào)用server_close()關(guān)閉它。
BaseServer中的常用方法,例子。
fileno() # 返回文件描述符 handle_request # 處理單個請求 serve_forever(poll_interval=0.5) # 一直運行直到收到shutdown()請求,每poll_interval檢查一次,后調(diào)用service_actions()結(jié)束 service_actions() # 結(jié)束操作 shutdown() # 停止信號 server_close() # 清除server address_family # 地址簇 RequestHandlerClass # 請求處理類 server_address # ip地址 socket # 同socket self.allow_reuse_adress # 允許重用地址 socket中socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) socket_type # socket使用的協(xié)議類型 self.setup() # 請求來之前 self.handle() # 請求來時 self.finish() # 請求處理之后 View Code作業(yè)
1.用戶加密認證
2.允許多個用戶登陸
3.每個用戶有自己的家目錄,不能互相訪問
4.對用戶進行磁盤配額,可用空間不同
5.允許用戶在ftp_server上隨意切換目錄
6.允許用戶查看當前目錄文件
7.允許用戶上傳下載文件,保證文件一致性
8.傳輸過程顯示進度條
作業(yè)
轉(zhuǎn)載于:https://www.cnblogs.com/zk71124720/p/9407286.html
總結(jié)
以上是生活随笔為你收集整理的NO.8:自学python之路------并行socket网络编程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Assigned 的迷思
- 下一篇: PYTHON 爬虫笔记七:Seleniu