日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

【python自动化第八篇:网络编程】

發(fā)布時(shí)間:2025/4/16 python 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【python自动化第八篇:网络编程】 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、拾遺

動(dòng)態(tài)導(dǎo)入模塊

  目的是為了在導(dǎo)入模塊的過程中將模塊以字符的格式導(dǎo)入。?

#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui lib = __import__("lib.aa") #傳統(tǒng)方法 lib.aa import importlib aa = importlib.import_module("lib.aa") #官方做法 print(aa.C().name)

?斷言

  類似于if,實(shí)際的意思就是如多對(duì)應(yīng)的條件為真就執(zhí)行,不為真就報(bào)錯(cuò)。

assert type(1223) is str print("this is str") #等同于 if type(1223) is str:exit("must be int") print("this is str")

二、socket繼續(xù)

  1、淺談server端的原理:

    (1)、申明socket實(shí)例 ? ? server = socket.socket(AF.INET(地址簇),sock.SOCK_STREAM(代表tcp/ip))

        地址簇分類:socket.AF_INET ----> ipv4 ? ?, ? ? ? ? ? ? ? ? ? ? ? socket.AF_INET6 -------> ipv6 ? ? ?, ? ? ? ?socket.AF_UNIX --------> ?本地通信

        協(xié)議類型:socket.SOCK_STREAM -----> tcp/ip ? ? , ? ? ? ? ? ??socket.SOCK_DGRAM -----> ?udp            

?    (2)、綁定ip地址和端口 ? ? ?server.bind(("localhost",port))

    ?(3)、開始監(jiān)聽:while True:

        conn,addr = server.accept() ? ?阻塞狀態(tài)

    ?(4)、循環(huán)接受信息

        while True:

          print("new conn",addr) ? #打印連接的客戶端ip

          data = conn.recv(1024) ? ? ? ? ? ? #接受數(shù)據(jù)大小(官方最大建議8192),這邊接收數(shù)據(jù)的時(shí)候默認(rèn)也是阻塞的         

          if not data: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?***如果客戶端 已斷開的話conn.recv就會(huì)接收到空數(shù)據(jù)

            break ? ? ? ? ? ??

          conn.send(data.upper()) ? ? ? ? ? ?#發(fā)送數(shù)據(jù)

? ? ? 淺談客戶端的原理:

    (1)、實(shí)例化一個(gè)socket ? ? client = socket.socket()

    (2)、定義一個(gè) 鏈接的地址和端口 ? ? ?client.connect(("server_ip",port))

    (3)、這會(huì)兒就可以發(fā)數(shù)據(jù)了 ? ?client.send(data)

    (4)、接收數(shù)據(jù) ? client.recv()

  2、通過socket實(shí)現(xiàn)一個(gè)簡(jiǎn)單的ssh協(xié)議:

    client端:

#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui import socket,os client = socket.socket() #實(shí)例化socket client.connect(("localhost",9999)) #開始連接啦while True: #發(fā)送數(shù)據(jù)啦cmd = input("請(qǐng)輸入命令>>:").strip()if len(cmd) == 0:continue #如果長(zhǎng)度為0,就繼續(xù)返回循環(huán)client.send(cmd.encode('utf-8')) #發(fā)送命令(byte)cmd_res = client.recv(1024) #接收返回結(jié)果print(cmd_res.decode()) #打印結(jié)果 client.close() #關(guān)閉連接

  server端:?

#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui import socket,osserver = socket.socket() #申明實(shí)例 server.bind(('localhost',9999)) #綁定ip和端口 server.listen() #等待連接while True:conn,addr= server.accept() #監(jiān)聽print("開始連接啦",addr)while True: #正式接受數(shù)據(jù)啦print("開始新連接啦")data = conn.recv(1024) #定義傳輸大小if not data: #如果客戶端斷開,那么就退出此次接收,重新回到監(jiān)聽狀態(tài)breakprint("開始 執(zhí)行客戶端命令",data)cmd_res = os.popen(data.decode()).read() #讀取客戶端命令(bytes轉(zhuǎn)換成str)print("接受之前:",len(cmd_res))if len(cmd_res) == 0:cmd_res = "cmd has no output ..."conn.send(cmd_res.encode('utf-8')) #向端發(fā)送數(shù)據(jù),必須是bytesprint("發(fā)送完成!") server.close() #斷開連接

    上面的基本連接模式會(huì)出現(xiàn)客戶端發(fā)送的指令客戶端不能一次性全部返回的問題,這樣的話解決方式只能有:超時(shí)和確認(rèn)緩沖區(qū)多少次發(fā)完的問題

    然而多少次將緩沖區(qū)的內(nèi)容發(fā)完呢?不曉得。。。所以只能通過在超時(shí)問題上做文章了

client:

#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui import socket,os client = socket.socket() #實(shí)例化socket client.connect(("localhost",9999)) #開始連接啦while True: #發(fā)送數(shù)據(jù)啦cmd = input("請(qǐng)輸入命令>>:").strip()if len(cmd) == 0:continue #如果長(zhǎng)度為0,就繼續(xù)返回循環(huán)client.send(cmd.encode('utf-8')) #發(fā)送命令(byte)cmd_res_size = client.recv(1024) #接受返回?cái)?shù)據(jù)的大小print("接受的數(shù)據(jù)",cmd_res_size) #打印接收大小received_size = 0received_data = b''while received_size < int(cmd_res_size.decode()): #只要不相等就一直收data = client.recv(1024)received_size += len(data) #每次接收到的數(shù)據(jù)有可能小于1024,所以要用len判斷received_data += data #每次讀取進(jìn)來的data寫入received_data# print(data.decode())else:print("cmd rees received done",received_size)print(received_data.decode()) client.close() #關(guān)閉連接 View Code

?

server:

#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui import socket,osserver = socket.socket() #申明實(shí)例 server.bind(('localhost',9999)) #綁定ip和端口 server.listen() #等待連接while True:conn,addr= server.accept() #監(jiān)聽print("開始連接啦",addr)while True: #正式接受數(shù)據(jù)啦print("等待新指令:")data = conn.recv(1024) #定義傳輸大小if not data: #如果客戶端斷開,那么就退出此次接收,重新回到監(jiān)聽狀態(tài)print("客戶端已經(jīng)斷開!")breakprint("執(zhí)行命令",data)cmd_res = os.popen(data.decode()).read() #讀取客戶端命令(bytes轉(zhuǎn)換成str)print("接受之前:",len(cmd_res))if len(cmd_res) == 0:cmd_res = "cmd has no output ..."conn.send(str(len(cmd_res.encode())).encode('utf-8')) #先發(fā)大小給客戶端conn.send(cmd_res.encode('utf-8')) #向客戶端發(fā)送數(shù)據(jù),必須是bytesprint("發(fā)送完成!") server.close() #斷開連接 View Code

?

  3.粘包問題

    server連續(xù)調(diào)用send的時(shí)候緩沖區(qū)會(huì)將挨著的兩次操作發(fā)給客戶端,導(dǎo)致兩次send的內(nèi)容都同時(shí)發(fā)給了客戶端,所以其中的一個(gè)方法就是在服務(wù)器端的send之間加入sleep時(shí)間,可以解決這個(gè)問題

? ? ?server:

#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui import socket,os,timeserver = socket.socket() #申明實(shí)例 server.bind(('localhost',9999)) #綁定ip和端口 server.listen() #等待連接while True:conn,addr= server.accept() #監(jiān)聽print("開始連接啦",addr)while True: #正式接受數(shù)據(jù)啦print("等待新指令:")data = conn.recv(1024) #定義傳輸大小if not data: #如果客戶端斷開,那么就退出此次接收,重新回到監(jiān)聽狀態(tài)print("客戶端已經(jīng)斷開!")breakprint("執(zhí)行命令",data)cmd_res = os.popen(data.decode()).read() #讀取客戶端命令(bytes轉(zhuǎn)換成str)print("接受之前:",len(cmd_res))if len(cmd_res) == 0:cmd_res = "cmd has no output ..."conn.send(str(len(cmd_res.encode())).encode('utf-8')) #先發(fā)大小給客戶端#time.sleep(0.5) #防止粘包的一種方法client_ack= conn.recv(1024) #等待確認(rèn)print('ack from client:',client_ack)conn.send(cmd_res.encode('utf-8')) #向客戶端發(fā)送數(shù)據(jù),必須是bytesprint("發(fā)送完成!") server.close() #斷開連接

  client:

#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui import socket,os client = socket.socket() #實(shí)例化socket client.connect(("localhost",9999)) #開始連接啦while True: #發(fā)送數(shù)據(jù)啦cmd = input("請(qǐng)輸入命令>>:").strip()if len(cmd) == 0:continue #如果長(zhǎng)度為0,就繼續(xù)返回循環(huán)client.send(cmd.encode('utf-8')) #發(fā)送命令(byte)cmd_res_size = client.recv(1024) #接受返回?cái)?shù)據(jù)的大小print("接受的數(shù)據(jù)",cmd_res_size) #打印接收大小client.send("準(zhǔn)備確認(rèn)啦".encode('utf-8'))received_size = 0received_data = b''while received_size < int(cmd_res_size.decode()): #只要不相等就一直收data = client.recv(1024)received_size += len(data) #每次接收到的數(shù)據(jù)有可能小于1024,所以要用len判斷received_data += data #每次讀取進(jìn)來的data寫入received_data# print(data.decode())else:print("cmd rees received done",received_size)print(received_data.decode()) client.close() #關(guān)閉連接

  4.簡(jiǎn)易的文件傳輸案例

    server端的設(shè)計(jì):

      • 讀取文件名
      • 檢測(cè)文件是否存在
      • 打開文件
      • 檢測(cè)文件大小
      • 發(fā)送文件大小和MD5值給客戶端
      • 等待客戶端確認(rèn)
      • 開始邊讀取邊發(fā)數(shù)據(jù)    
#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui import socket,os,time,hashlibserver = socket.socket() #申明實(shí)例 server.bind(('localhost',9999)) #綁定ip和端口 server.listen() #等待連接while True:conn,addr= server.accept() #監(jiān)聽print("開始連接啦",addr)while True: #正式接受數(shù)據(jù)啦print("等待新指令:")data = conn.recv(1024) #定義傳輸大小if not data: #如果客戶端斷開,那么就退出此次接收,重新回到監(jiān)聽狀態(tài)print("客戶端已經(jīng)斷開!")breakcmd,filename = data.decode().split() #分割命令和文件名稱print(filename) #打印文件名if os.path.isfile(filename): #判斷是否為文件f = open(filename,'rb') #打開文件m = hashlib.md5() #定義MD5加密方式file_size = os.stat(filename).st_size #確定文件大小conn.send(str(file_size).encode()) #發(fā)送文件大小conn.recv(1024) #等待確認(rèn)for line in f: #讀取文件m.update(line) #邊讀取邊加密conn.send(line) #邊發(fā)送文件print('file md5',m.hexdigest()) #打印文件的MD5f.close() #關(guān)閉文件conn.send(m.hexdigest().encode()) #發(fā)送MD5print("發(fā)送完成!!")server.close()

  client端:

#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui import socket,os,hashlibclient = socket.socket() #實(shí)例化socket client.connect(("localhost",9999)) #開始連接啦while True: #發(fā)送數(shù)據(jù)啦cmd = input(">>:").strip()if len(cmd) == 0:continue #如果長(zhǎng)度為0,就繼續(xù)返回循環(huán)if cmd.startwith('get'): #定義開始client.send(cmd.encode()) #客戶端發(fā)送命令server_resbonce = client.recv(1024) #接收服務(wù)器端數(shù)據(jù)print("server resbonce:",server_resbonce)client.send("準(zhǔn)備接收文件".encode())file_total_size = int(server_resbonce.decode()) #定義接受的文件總大小received_size=0 #初始接收文件filename = cmd.split()[1] #獲取文件名f = open(filename + '.new','wb') #開始寫文件m = hashlib.md5() #定義MD5加密while received_size < file_total_size: #如果接收的文件小于總文件大小,就執(zhí)行如下data = client.recv(1024) #定義接收文件received_size+=len(data) #接受的文件大小變化m.update(data) #生成客戶端接受的MD5f.write(data) #寫入數(shù)據(jù)#print(file_total_size,received_size) #打印文件接受大小和總大小else:new_file_md5 = m.hexdigest()print("接受完了文件:",file_total_size,received_size)f.close() #關(guān)閉文件server_md5 = client.recv(1024) #接收服務(wù)器端MD5print(server_md5,new_file_md5) #對(duì)比MD5client.close()

  

?

轉(zhuǎn)載于:https://www.cnblogs.com/wanghui1991/p/5865848.html

總結(jié)

以上是生活随笔為你收集整理的【python自动化第八篇:网络编程】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。