日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

Python--day8--Socket编程/异常处理

發(fā)布時(shí)間:2025/4/5 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python--day8--Socket编程/异常处理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

介紹:

學(xué)習(xí)的第二階段,網(wǎng)絡(luò)編程。基于Python3 2016年12月29日 14:00:58



目錄:

  • Socket介紹

  • Socket簡(jiǎn)單交互實(shí)例

  • ssh模擬

  • Socket基本語(yǔ)法

  • SocketServer

  • 異常處理




  • Socket,又稱作?套接字。用于描述IP地址和端口,是一個(gè)通信鏈的句柄,應(yīng)用程序通常通過(guò)“套接字”向網(wǎng)絡(luò)發(fā)出請(qǐng)求或者應(yīng)答網(wǎng)絡(luò)請(qǐng)求。

    Socket 模塊 是針對(duì) ?服務(wù)器端?和?客戶端Socket ?進(jìn)行 ??打開(kāi) 讀寫(xiě) ?關(guān)閉

    服務(wù)器:發(fā)送一條消息

    1 2 3 4 5 6 7 8 9 10 11 12 13 import?socket#標(biāo)準(zhǔn)庫(kù) ip_port?=?('127.0.0.1',9998)?##聲明 sk?=?socket.socket()????##生成一個(gè)句柄 sk.bind(ip_port) sk.listen(5)????##監(jiān)聽(tīng) while?True: ????print('server?waiting...') ????conn,addr?=?sk.accept()???##會(huì)把客戶端的端口和IP,生成一個(gè)實(shí)例,只為這個(gè)客戶端服務(wù) ##??生成的實(shí)例,地址 ????client_data?=?conn.recv(1024)??##1024個(gè)字節(jié)/比特 ????print(str(client_data,'utf8')) ????conn.sendall(bytes('不要回答,不要回答,不要回答','utf8')) ????conn.close()

    客戶端:發(fā)送一條信息

    1 2 3 4 5 6 7 8 import?socket ip_port?=?('127.0.0.1',9998) sk?=?socket.socket() sk.connect(ip_port) sk.sendall(bytes('請(qǐng)求占領(lǐng)地球','utf8')) server_reply?=?sk.recv(1024) print(str(server_reply,'utf8')) sk.close()



    服務(wù)器和客戶端交互消息

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 import?socket#標(biāo)準(zhǔn)庫(kù) ip_port?=?('127.0.0.1',9998)?##聲明 sk?=?socket.socket()????##生成一個(gè)句柄 sk.bind(ip_port) sk.listen(5)????##監(jiān)聽(tīng) while?True: ????print('server?waiting...') ????conn,addr?=?sk.accept()??##會(huì)把客戶端的端口和IP,生成一個(gè)實(shí)例,只為這個(gè)客戶端服務(wù) ##??生成的實(shí)例,地址 ????client_data?=?conn.recv(1024)??##1024個(gè)字節(jié)/比特 ????print(str(client_data,'utf8')) ????conn.sendall(bytes('不要回答,不要回答,不要回答','utf8')) ????while?True: ????????client_data?=?conn.recv(1024) ????????print(str(client_data,'utf8')) ????????server_response?=?input("\033[31;1m>>:\033[0m").strip() ????????conn.send(bytes(server_response,'utf8')) ????conn.close() import?socket ip_port?=?('127.0.0.1',9998) sk?=?socket.socket() sk.connect(ip_port) sk.sendall(bytes('請(qǐng)求占領(lǐng)地球','utf8')) server_reply?=?sk.recv(1024) print(str(server_reply,'utf8')) while??True: ????user_input?=input(">>:").strip() ????sk.sendall(bytes(user_input,'utf8')) ????server_reply?=?sk.recv(1024) ????print(str(server_reply,?'utf8')) sk.close()

    服務(wù)器和多個(gè)客戶端,第一個(gè)客戶端斷開(kāi)后,第二個(gè)進(jìn)行連接

    1 2 3 4 5 6 7 8 9 conn.sendall(bytes('不要回答,不要回答,不要回答','utf8')) while?True: ????try: ????????client_data?=?conn.recv(1024) ????????print("recv:",str(client_data,'utf8')) ????except??Exception:??####??前面是windows的?,后面是linux??:if?not??client_data:break? ????????print("client??closed?,break") ????????break ????conn.send(client_data)



    ssh模擬執(zhí)行命令

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import?socketimport?os,subprocess server?=?socket.socket()?#獲得socket實(shí)例server.setsockopt(socket.SOL_SOCKET,?socket.SO_REUSEADDR,?1) server.bind(("localhost",9999))?#綁定ip?portserver.listen()??#開(kāi)始監(jiān)聽(tīng)while?True:?#第一層loop ????print("等待客戶端的連接...") ????conn,addr?=?server.accept()?#接受并建立與客戶端的連接,程序在此處開(kāi)始阻塞,只到有客戶端連接進(jìn)來(lái)... ????print("新連接:",addr?)????while?True: ????????data?=?conn.recv(1024)????????if?not?data:????????????print("客戶端斷開(kāi)了...")????????????break?#這里斷開(kāi)就會(huì)再次回到第一次外層的loop ????????print("收到命令:",data)????????#res?=?os.popen(data.decode()).read()?#py3?里socket發(fā)送的只有bytes,os.popen又只能接受str,所以要decode一下 ????????res?=?subprocess.Popen(data,shell=True,stdout=subprocess.PIPE).stdout.read()?#跟上面那條命令的效果是一樣的 ????????if?len(res)?==?0: ????????????res?=?"cmd?exec?success,has?not?output!".encode("utf-8") ????????conn.send(str(len(res)).encode("utf-8"))?#發(fā)送數(shù)據(jù)之前,先告訴客戶端要發(fā)多少數(shù)據(jù)給它 ????????print("等待客戶ack應(yīng)答...") ????????client_final_ack?=?conn.recv(1024)?#等待客戶端響應(yīng) ????????print("客戶應(yīng)答:",client_final_ack.decode())????????print(type(res)) ????????conn.sendall(res)?#發(fā)送端也有最大數(shù)據(jù)量限制,所以這里用sendall,相當(dāng)于重復(fù)循環(huán)調(diào)用conn.send,直至數(shù)據(jù)發(fā)送完畢server.close()
    import?socketimport?sysclient?=?socket.socket()client.connect(("localhost",9999))while?True:msg?=?input(">>:").strip()????if?len(msg)?==?0:continueclient.send(?msg.encode("utf-8")?)res_return_size??=?client.recv(1024)?#接收這條命令執(zhí)行結(jié)果的大小print("getting?cmd?result?,?",?res_return_size)total_rece_size?=?int(res_return_size)????print("total?size:",res_return_size)client.send("準(zhǔn)備好接收了,發(fā)吧loser".encode("utf-8"))received_size?=?0?#已接收到的數(shù)據(jù)cmd_res?=?b''f?=?open("test_copy.html","wb")#把接收到的結(jié)果存下來(lái),一會(huì)看看收到的數(shù)據(jù)?對(duì)不對(duì)while?received_size?!=?total_rece_size:?#代表還沒(méi)收完data?=?client.recv(1024)received_size?+=?len(data)?#為什么不是直接1024,還判斷l(xiāng)en干嘛,注意,實(shí)際收到的data有可能比1024少cmd_res?+=?data????else:????????print("數(shù)據(jù)收完了",received_size)????????#print(cmd_res.decode())f.write(cmd_res)?#把接收到的結(jié)果存下來(lái),一會(huì)看看收到的數(shù)據(jù)?對(duì)不對(duì)#print(data.decode())?#命令執(zhí)行結(jié)果client.close()

    Socket基本語(yǔ)法

    Socket ?Families 地址簇

    socket.AF_UNIX ? ?unix本機(jī)進(jìn)程間通信

    socket.AF_INET?? ipv4

    socket.AF_INET6 ?ipv6

    Scoket ?Types

    socket.SOCK_STREAM?? ?TCP

    socket.SOCK_DGRAM ? ? UDP

    socket.SOCK_RAW ? ? ? ?原始套接字

    socket.SOCK_RDM ? ? ?可靠的UDP

    socket.socket(family=AF_INET,?type=SOCK_STREAM,?proto=0,?fileno=None)


    socket.socketpair([family[,?type[,?proto]]]) ?


    socket.create_connection(address[,?timeout[,?source_address]])


    socket.getaddrinfo(host,?port,?family=0,?type=0,?proto=0,?flags=0) #獲取要連接的對(duì)端主機(jī)地址


    sk.bind(address)

      s.bind(address) 將套接字綁定到地址。address地址的格式取決于地址族。在AF_INET下,以元組(host,port)的形式表示地址。

    sk.listen(backlog)

      開(kāi)始監(jiān)聽(tīng)傳入連接。backlog指定在拒絕連接之前,可以掛起的最大連接數(shù)量。

    sk.setblocking(bool)???

      是否阻塞(默認(rèn)True),如果設(shè)置False,那么accept和recv時(shí)一旦無(wú)數(shù)據(jù),則報(bào)錯(cuò)。

    sk.accept()

      接受連接并返回(conn,address),其中conn是新的套接字對(duì)象,可以用來(lái)接收和發(fā)送數(shù)據(jù)。address是連接客戶端的地址。

      接收TCP 客戶的連接(阻塞式)等待連接的到來(lái)

    sk.connect(address)

      連接到address處的套接字。一般,address的格式為元組(hostname,port),如果連接出錯(cuò),返回socket.error錯(cuò)誤。

    sk.connect_ex(address)

      同上,只不過(guò)會(huì)有返回值,連接成功時(shí)返回 0 ,連接失敗時(shí)候返回編碼,例如:10061

    sk.close()

      關(guān)閉套接字

    sk.recv(bufsize[,flag])

      接受套接字的數(shù)據(jù)。數(shù)據(jù)以字符串形式返回,bufsize指定最多可以接收的8192 ?數(shù)量。flag提供有關(guān)消息的其他信息,通常可以忽略。

    sk.recvfrom(bufsize[.flag])

      與recv()類似,但返回值是(data,address)。其中data是包含接收數(shù)據(jù)的字符串,address是發(fā)送數(shù)據(jù)的套接字地址。

    sk.send(string[,flag])

      將string中的數(shù)據(jù)發(fā)送到連接的套接字。返回值是要發(fā)送的字節(jié)數(shù)量,該數(shù)量可能小于string的字節(jié)大小。即:可能未將指定內(nèi)容全部發(fā)送。

    sk.sendall(string[,flag])

      將string中的數(shù)據(jù)發(fā)送到連接的套接字,但在返回之前會(huì)嘗試發(fā)送所有數(shù)據(jù)。成功返回None,失敗則拋出異常。

    ? ? ? 內(nèi)部通過(guò)遞歸調(diào)用send,將所有內(nèi)容發(fā)送出去。

    sk.sendto(string[,flag],address)

      將數(shù)據(jù)發(fā)送到套接字,address是形式為(ipaddr,port)的元組,指定遠(yuǎn)程地址。返回值是發(fā)送的字節(jié)數(shù)。該函數(shù)主要用于UDP協(xié)議。

    sk.settimeout(timeout)

      設(shè)置套接字操作的超時(shí)期,timeout是一個(gè)浮點(diǎn)數(shù),單位是秒。值為None表示沒(méi)有超時(shí)期。一般,超時(shí)期應(yīng)該在剛創(chuàng)建套接字時(shí)設(shè)置,因?yàn)樗鼈兛赡苡糜谶B接的操作(如 client 連接最多等待5s )

    sk.getpeername()

      返回連接套接字的遠(yuǎn)程地址。返回值通常是元組(ipaddr,port)。

    sk.getsockname()

      返回套接字自己的地址。通常是一個(gè)元組(ipaddr,port)

    sk.fileno()

      套接字的文件描述符


    SockerServer ? ? ? ? 多線程

    +------------+|?BaseServer?|+------------+??????|??????v+-----------+????????+------------------+|?TCPServer?|------->|?UnixStreamServer?|+-----------+????????+------------------+??????|??????v+-----------+????????+--------------------+|?UDPServer?|------->|?UnixDatagramServer?|+-----------+????????+--------------------+
    • class?socketserver.ForkingTCPServer

    • class?socketserver.ForkingUDPServer

    • class?socketserver.ThreadingTCPServer

    • class?socketserver.ThreadingUDPServer

    例子


    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import?socketserver class?MyTCPHandler(socketserver.BaseRequestHandler): ????""" ????The?request?handler?class?for?our?server. ????It?is?instantiated?once?per?connection?to?the?server,?and?must ????override?the?handle()?method?to?implement?communication?to?the ????client. ????""" ????def?handle(self): ????????#?self.request?is?the?TCP?socket?connected?to?the?client ????????self.data?=?self.request.recv(1024).strip() ????????print("{}?wrote:".format(self.client_address[0])) ????????print(self.data) ????????#?just?send?back?the?same?data,?but?upper-cased ????????self.request.sendall(self.data.upper()) if?__name__?==?"__main__": ????HOST,?PORT?=?"localhost",?9999 ????#?Create?the?server,?binding?to?localhost?on?port?9999 ????server?=?socketserver.ThreadingTCPServer((HOST,?PORT),?MyTCPHandler) ????#?Activate?the?server;?this?will?keep?running?until?you ????#?interrupt?the?program?with?Ctrl-C ????server.serve_forever()



    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import?socket import?sys HOST,?PORT?=?"localhost",?9999 data?=?"?".join(sys.argv[1:]) #?Create?a?socket?(SOCK_STREAM?means?a?TCP?socket) sock?=?socket.socket(socket.AF_INET,?socket.SOCK_STREAM) try: ????#?Connect?to?server?and?send?data ????sock.connect((HOST,?PORT)) ????sock.sendall(bytes(data?+?"\n",?"utf-8")) ????#?Receive?data?from?the?server?and?shut?down ????received?=?str(sock.recv(1024),?"utf-8") finally: ????sock.close() print("Sent:?????{}".format(data)) print("Received:?{}".format(received))




    異常處理

    • isinstacne(obj,cls)??判斷一個(gè)對(duì)象是否是類cls的對(duì)象

    • issubclass(sub,super) ?檢查sub類是否是super類的派生類(子類)

    異常基礎(chǔ)

    1 2 3 4 5 6 7 8 9 10 11 ?while?True: ????num1?=?input('num1:') ????num2?=?input('num2:') ????try: ????????num1?=?int(num1) ????????num2?=?int(num2) ????????result?=?num1?+?num2 ????except?Exception?as?e:??##??萬(wàn)能??所有的異常 ????????print('出現(xiàn)異常,信息如下:') ????????print(e) ????pass

    常見(jiàn)錯(cuò)誤

    AttributeError ? ? ? 試圖訪問(wèn)一個(gè)對(duì)象沒(méi)有的樹(shù)形,比如foo.x,但是foo沒(méi)有屬性x
    IOError ? ? ? ? ? ? ? ? 輸入/輸出異常;基本上是無(wú)法打開(kāi)文件
    ImportError ? ? ? ? ?無(wú)法引入模塊或包;基本上是路徑問(wèn)題或名稱錯(cuò)誤
    IndentationError ? 語(yǔ)法錯(cuò)誤(的子類)?;代碼沒(méi)有正確對(duì)齊

    IndexError ? ? ? ? ? ?下標(biāo)索引超出序列邊界,比如當(dāng)x只有三個(gè)元素,卻試圖訪問(wèn)x[5]

    KeyError ? ? ? ? ? ? ? ?試圖訪問(wèn)字典里不存在的鍵

    KeyboardInterrupt?Ctrl+C被按下

    NameError ? ? ? ? ? ? 使用一個(gè)還未被賦予對(duì)象的變量

    SyntaxError ? ? ? ? ? ?Python代碼非法,代碼不能編譯(個(gè)人認(rèn)為這是語(yǔ)法錯(cuò)誤,寫(xiě)錯(cuò)了)

    TypeError ? ? ? ? ? ?????傳入對(duì)象類型與要求的不符合

    UnboundLocalError ?試圖訪問(wèn)一個(gè)還未被設(shè)置的局部變量,基本上是由于另有一個(gè)同名的全局變量,

    導(dǎo)致你以為正在訪問(wèn)它

    ValueError ? ? ? ? ? ? ? ?傳入一個(gè)調(diào)用者不期望的值,即使值的類型是正確的



    自定義異常

    1 2 3 4 5 6 7 8 9 class?WupeiqiException(Exception): ????def?__init__(self,?msg): ????????self.message?=?msg ????def?__str__(self): ????????return?self.message try: ????raise?WupeiqiException('我的異常') except?WupeiqiException?as?e: ????print(e)



    異常其他結(jié)構(gòu)

    try:

    ????# 主代碼塊

    ????pass

    except?KeyError as e:

    ????# 異常時(shí),執(zhí)行該塊

    ????pass

    else:

    ????# 主代碼塊執(zhí)行完,執(zhí)行該塊

    ????pass

    finally:

    ????# 無(wú)論異常與否,最終執(zhí)行該塊

    ????pass

    assert ?條件 ? 斷言

    assert 1 == 1? ? ?










    本文轉(zhuǎn)自 295631788 51CTO博客,原文鏈接:,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者

    總結(jié)

    以上是生活随笔為你收集整理的Python--day8--Socket编程/异常处理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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