day30 網絡編程
阿新 • • 發佈:2017-11-28
linux 模塊 num from 服務端 one ont 技術 day3
subprocess模塊:
這個模塊的作用就是跟系統操作相關的調用系統命令,類似於os模塊,比os更加強大。
它本身自帶一個管道,這個管道就類似於臨時存儲數據的的容器,把中間值存入裏面,
然後當需要的時候就從中取出。取出的時候裏面有多少就可以取出多少,同一份內容不會重復取出,
意思就是只有一份內容,你反復執行取出操做,它只能給你倒出一次,倒完了就沒有了。
然後管道裏面的執行命令分為錯誤命令和正確命令,分別存儲,用不同的關鍵字操作。
import subprocess obj=subprocess.Popen(‘dir‘,shell=True, stdoutView Code=subprocess.PIPE, stderr=subprocess.PIPE, ) # print(‘========hahahahahah‘) # print(obj.stdout.read().decode(‘gbk‘)) # print(obj.stdout.read().decode(‘gbk‘)) # print(obj.stdout.read().decode(‘gbk‘)) # print(obj.stdout.read().decode(‘gbk‘)) # print(obj.stdout.read().decode(‘gbk‘))print(obj.stderr.read().decode("gbk"))
跟subprocess模塊相關操作:
服務端
import subprocess from socket import * server=socket(AF_INET,SOCK_STREAM) server.bind((‘127.0.0.1‘,8081)) # print(server) server.listen(5) while True: conn,addr=server.accept() # print(conn) print(addr) whileView CodeTrue: try: cmd=conn.recv(8096) if not cmd:break #針對linux #執行命令 cmd=cmd.decode(‘utf-8‘) #調用模塊,執行命令,並且收集命令的執行結果,而不是打印 obj = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) stdout=obj.stdout.read() stderr=obj.stderr.read() #發送命令的結果 conn.send(stdout+stderr) except ConnectionResetError: break conn.close() server.close()
同上,客戶端:
from socket import * client=socket(AF_INET,SOCK_STREAM) client.connect((‘127.0.0.1‘,8081)) while True: cmd=input(‘>>: ‘).strip() if not cmd:continue client.send(cmd.encode(‘utf-8‘)) data=client.recv(1024) print(data.decode(‘gbk‘)) client.close()View Code
粘包現象:
服務端: import time from socket import * server=socket(AF_INET,SOCK_STREAM) server.bind((‘127.0.0.1‘,8082)) server.listen(5) conn,addr=server.accept() # res1=conn.recv(1) # print(res1) # res2=conn.recv(1) # res3=conn.recv(1) # res4=conn.recv(1) # res5=conn.recv(1) # print(res2) # print(res3) # print(res4) # print(res5) # res1=conn.recv(1) # print(res1) # time.sleep(4) # res2=conn.recv(1024) # print(res2) print(conn.recv(1111111111111111111111111111111111111111111)) print(conn.recv(5)) #=============================================== 客戶端 import time from socket import * client=socket(AF_INET,SOCK_STREAM) client.connect((‘127.0.0.1‘,8082)) client.send(b‘hello‘) # time.sleep(3) client.send(b‘world‘)View Code
struct模塊:
它就是把數字轉成固定長度的bytes類型。
struct.error: ‘i‘ format requires -2147483648 <= number <= 2147483647 #這個是範圍
import struct #幫我們把數字轉成固定長度的bytes類型 res=struct.pack(‘i‘,123123) print(res,len(res)) res1=struct.unpack(‘i‘,res) print(res1[0]) # 有興趣可以把上圖裏的都試一遍,這裏只是試了一種方法,iView Code
服務端 import subprocess import struct from socket import * server=socket(AF_INET,SOCK_STREAM) server.bind((‘127.0.0.1‘,8084)) # print(server) server.listen(5) while True: conn,addr=server.accept() # print(conn) print(addr) while True: try: cmd=conn.recv(8096) if not cmd:break #針對linux #執行命令 cmd=cmd.decode(‘utf-8‘) #調用模塊,執行命令,並且收集命令的執行結果,而不是打印 obj = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) stdout=obj.stdout.read() stderr=obj.stderr.read() #第一步:制作報頭: total_size=len(stdout)+len(stderr) header=struct.pack(‘i‘,total_size) # 這裏是打成一個包,包裏面是一個數字的固定長度 #第二步:先發報頭(固定長度) conn.send(header) #第三步:發送命令的結果 conn.send(stdout) conn.send(stderr) except ConnectionResetError: break conn.close() server.close()View Code
客戶端 import struct from socket import * client=socket(AF_INET,SOCK_STREAM) client.connect((‘127.0.0.1‘,8084)) while True: cmd=input(‘>>: ‘).strip() if not cmd:continue client.send(cmd.encode(‘utf-8‘)) #第一步:收到報頭 header=client.recv(4) total_size=struct.unpack(‘i‘,header)[0] # 這裏是把接收到的數據解包,得到它原本的樣子,(類似於壓縮解壓縮) #第二步:收完整真實的數據 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()View Code
解決粘包問題:終結篇
import struct #幫我們把數字轉成固定長度的bytes類型 # res=struct.pack(‘i‘,123123) # print(res,len(res)) # # res1=struct.unpack(‘i‘,res) # print(res1[0]) # res=struct.pack(‘q‘,121231231233123) # print(res,len(res)) import json header_dic={ ‘md5‘:‘asdfasdfasdfasdfasdfasdf‘, ‘total_size‘:1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111, ‘filename‘:‘a.txt‘ } header_json=json.dumps(header_dic) header_bytes=header_json.encode(‘utf-8‘) print(len(header_bytes)) header_size=struct.pack(‘i‘,len(header_bytes)) # conn.send(header_size) ##recv(4) # conn.send(header_bytes) #recv(報頭長度) # conn.send(stdout) # conn.send(stderr)View Code
服務端: import subprocess import struct import json from socket import * server=socket(AF_INET,SOCK_STREAM) server.bind((‘127.0.0.1‘,8086)) # print(server) server.listen(5) while True: conn,addr=server.accept() # print(conn) print(addr) while True: try: cmd=conn.recv(8096) if not cmd:break #針對linux #執行命令 cmd=cmd.decode(‘utf-8‘) #調用模塊,執行命令,並且收集命令的執行結果,而不是打印 obj = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) stdout=obj.stdout.read() stderr=obj.stderr.read() # 1:先制作報頭,報頭裏放:數據大小, md5, 文件 header_dic = { ‘total_size‘:len(stdout)+len(stderr), ‘md5‘: ‘xxxxxxxxxxxxxxxxxxx‘, ‘filename‘: ‘xxxxx‘, ‘xxxxx‘:‘123123‘ } header_json = json.dumps(header_dic) header_bytes = header_json.encode(‘utf-8‘) header_size = struct.pack(‘i‘, len(header_bytes)) # 2: 先發報頭的長度 conn.send(header_size) # 3:先發報頭 conn.send(header_bytes) # 4:再發送真實數據 conn.send(stdout) conn.send(stderr) except ConnectionResetError: break conn.close() server.close()View Code
客戶端: import struct import json from socket import * client=socket(AF_INET,SOCK_STREAM) client.connect((‘127.0.0.1‘,8086)) while True: cmd=input(‘>>: ‘).strip() if not cmd:continue client.send(cmd.encode(‘utf-8‘)) # 1:先收報頭長度 obj = client.recv(4) header_size = struct.unpack(‘i‘, obj)[0] # 2:先收報頭,解出報頭內容 header_bytes = client.recv(header_size) header_json = header_bytes.decode(‘utf-8‘) header_dic = json.loads(header_json) print(header_dic) total_size = header_dic[‘total_size‘] # 3:循環收完整數據 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()View Code
day30 網絡編程