下面的例子是簡單的ssh 登入,其實也就是客戶端把指令傳送給伺服器。伺服器把結果返還給客戶端,客戶端再在終端展現服務端**:
#author:bigbao
#date:2018/7/18
# 我們之前沒有實現併發的原因是,我們之前是鏈結迴圈加通訊迴圈,我們只有建立連線後才能通訊,通訊的過程中騰不出手來建立連線
# 所以現在我們得把鏈結迴圈和通訊迴圈給分開,乙個class一直在建立連線,乙個class一直在通訊
# 我們之前的是我們必須建立過鏈結之後立馬去通訊,通過過程中部可以去建立連線
'''socketserver
封裝了多程序,多執行緒
同時還封裝了多路復用,把我們的程式效能發揮到機制
'''import socketserver
import subprocess
import json
import struct
# 通訊迴圈
class mytcphandler(socketserver.baserequesthandler): # baserequesthandler 專門用來負責處理通訊相關資訊的
def handle(self): # 這裡必須定義乙個handle方法,而且方法名必須是handle, sockerserver 會自動去呼叫handle這個方法
print(self.request) # 這裡的self.request 相當於我們之前看到的conn那個物件( conn,client_addr=server.accept() )
while true:
try:
recv_cliend_cmd = self.request.recv(1024) #接收客戶端的指令
if not recv_cliend_cmd:break
# 下面就要對客戶端傳送的指令進行處理了
obj=subprocess.popen(recv_cliend_cmd.decode('utf-8'),shell=true,
stdout=subprocess.pipe,
stderr=subprocess.pipe)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
# 下面開始建立報頭(隨意寫的),這裡我們真正用到的就是字典裡的total_size
header_dic=
header_json = json.dumps(header_dic)
header_bytes = header_json.encode('utf-8')
self.request.send(struct.pack('i',len(header_bytes))) # 這個傳送過去為固定的位元組數 4 個,所以客戶端第一次接收四個位元組即可
self.request.send(header_bytes)
self.request.send(stdout)
self.request.send(stderr)
except connectionreseterror:break
self.request.close()
# 連線迴圈
if __name__ == '__main__':
server = socketserver.threadingtcpserver(('127.0.0.1',8080),mytcphandler) #基於tcp的多執行緒服務端
server.serve_forever()
# 客戶端發來請求,就建立乙個連線,server 立馬造乙個執行緒,然後再把mytcphandler 類例項化得到乙個物件,觸發物件下面的handle方法,把連線丟給 handle 方法(handle方法下的self.request 就是建立的連線)
# 也就是說客戶端來乙個連線,建立後就會觸發通訊迴圈的的handle 方法,我們可以看一下self.request 列印出來的東西就是本地ip:埠 客戶端ip:埠
客戶端**#author:bigbao
#date:2018/7/18
import socket
import struct
import json
client = socket.socket(socket.af_inet,socket.sock_stream)
client.connect(('127.0.0.1',8080))
while true:
cmd = input('please input your cmd: ').strip()
if not cmd:continue
client.send(cmd.encode('utf-8'))
obj = client.recv(4)
header_size = struct.unpack('i',obj)[0]
header_bytes = client.recv(header_size)
header_json = header_bytes.decode('utf-8')
header_dic = json.loads(header_json)
total_size = header_dic['total_size']
recv_size = 0
res = b''
while recv_size < total_size:
recv_data = client.recv(1024)
res+=recv_data
recv_size+= len(recv_data)
print(res.decode('gbk'))
client.close()
我們上面處理的黏包問題是發生在服務端發資料給客戶端,客戶端的資料接收不完全的解決方案。要是涉及到兩邊都有黏包問題的話,解決方案也是上面一樣解決
python 網路程式設計學習 套接字socket
以前也學過套接字程式設計,這次想系統全面的學習下python網路程式設計的使用。做這個,為檢測進度,也為後續留下筆記和足跡。socket 常用函式 socket.gethostname socket.gethostbyname import socket host socket.gethostnam...
Python網路程式設計學習筆記一 socket模組
coding utf 8 主要測試python網路程式設計中socket模組的使用 涉及到的技術點 套接字 面向連線的還有非面向連線套接字 tcp面向連線 udp非面向連線 1 匯入socket 2 建立socket socket三要素 1 socket family,2 socket type 3...
Python 併發程式設計
1.程序 執行緒 協程基本概念,建立 使用 2.協程的應用 生成器 第三方模組 3.併發的實踐 程式執行起來之後建立的乙個程序。建立程序已經學過使用multiprocessing.process類建立 1 multiprocessing.process 指定target引數,建立物件 2 繼承mul...