Python Socket 編程知識(shí)點(diǎn)詳細(xì)介紹
前言:
Socket又稱為套接字,它是所有網(wǎng)絡(luò)通信的基礎(chǔ)。網(wǎng)絡(luò)通信其實(shí)就是進(jìn)程間的通信,Socket主要是使用IP地址,協(xié)議,端口號(hào)來標(biāo)識(shí)一個(gè)進(jìn)程。端口號(hào)的范圍為0~65535(用戶端口號(hào)一般大于1024),協(xié)議有很多種,一般我們經(jīng)常用到的就是TCP,IP,UDP。下面我們來詳細(xì)了解下Socket吧。
一、導(dǎo)入Socket模塊
因?yàn)橐僮魈捉幼?,所以需要用到套接字模塊,系統(tǒng)中自帶的就很不錯(cuò),下面我們來導(dǎo)入:
import socket
二、Socket基本用法
1.建立一個(gè)簡(jiǎn)單的Socket連接
#創(chuàng)建Tcp/Ip套接字 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #流式Socket #創(chuàng)建Udp/Ip套接字 s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #數(shù)據(jù)報(bào)式Socket socket.AF_UNIX ?#只能夠用于單一的Unix系統(tǒng)進(jìn)程間通信 socket.AF_INET6 ?#只能夠用于IPv6通信 socket.SOCK_RAW ?#原始套接字,可以處理ICMP、ARP等網(wǎng)絡(luò)報(bào)文,其它的不行 socket.SOCK_SEQPACKET ?#可靠的連續(xù)數(shù)據(jù)包服務(wù)
2.協(xié)議對(duì)應(yīng)端口
應(yīng)用程序 FTP TFTP TELNET SMTP DNS HTTP SSH MYSQL POP3 MONGO
端口 21,20 69 23 25 53 80 22 3306 110 27017
協(xié)議 TCP UDP TCP TCP UDP TCP TCP TCP TCP TCP
3.Socket函數(shù)
#創(chuàng)建Socket連接,比Connect更高級(jí),可以自動(dòng)解析不是數(shù)字的host地址,兼容IPv4和 IPv6 socket.create_connection(address=('localhost',4320),timeout=4,source_address=('localhost',4320)) ?#前后兩個(gè)端口號(hào)一定要是一致,不然會(huì)報(bào)錯(cuò) #構(gòu)建一對(duì)已連接的套接字對(duì)象,新創(chuàng)建的套接字都是不可繼承的 socket.socketpair(family=socket.AF_INET,type=socket.SOCK_STREAM,proto=0) #從文件描述符獲取到socket連接對(duì)象 socket.fromfd(fd=ab.fileno(),family=socket.AF_INET,type=socket.SOCK_STREAM,proto=0) #套接字對(duì)象的類型 socket.SocketType #返回套接字的5元組列表地址 ,支持IPV4/IPV6解析 socket.getaddrinfo(host='localhost',port=3453,family=socket.AF_INET,type=socket.SOCK_STREAM,proto=socket.IPPROTO_TCP,flags=0) output: [(<AddressFamily.AF_INET: 2>, <SocketKind.SOCK_STREAM: 1>, 6, '', ('127.0.0.1', 3453))] #獲取主機(jī)名 socket.gethostname() socket.getfqdn() socket.getfqdn(socket.gethostname()) #將主機(jī)名轉(zhuǎn)化為IP地址 socket.gethostbyname('www.baidu.com') #不支持IPV6解析 socket.gethostbyname_ex('www.baidu.com') #返回三元組,(主機(jī)名,相同地址的其它可用主機(jī)名的列表,IPv4 地址列表) #網(wǎng)絡(luò)ip地址 socket.gethostbyname(socket.getfqdn(socket.gethostname())) #將ip地址轉(zhuǎn)化為主機(jī)名,返回三元組(主機(jī)名,相同地址的其它可用主機(jī)名的列表,IPv4地址列表),支持IPV4/IPV6 socket.gethostbyaddr('192.168.1.4') #解析主機(jī)名或者IP地址 socket.getnameinfo(('192.168.1.4',5434),0) #判斷是否支持IPV6 socket.has_ipv6 #返回服務(wù)所使用的端口號(hào) socket.getservbyname('https','tcp') #第一個(gè)參數(shù)為服務(wù)協(xié)議:Https,Http;第二個(gè)為傳輸協(xié)議:Tcp Udp #返回端口所對(duì)應(yīng)的服務(wù) socket.getservbyport(443,'tcp') #設(shè)置主機(jī)名(僅限于Unix) socket.sethostname(name) #返回網(wǎng)卡信息的列表(僅限于Unix) socket.if_nameindex() #32位字節(jié)存儲(chǔ)Ip地址(序列化) socket.inet_aton('127.0.0.1') #將32位字節(jié)轉(zhuǎn)化為Ip地址(反序列化) socket.inet_ntoa(b'\x7f\x00\x00\x01')
4.套接字函數(shù)
1).服務(wù)器端函數(shù)
s.bind((host,port)) #將地址綁定到套接字,以(host,port)的元祖形式 s.listen(num) ?#建立最多num個(gè)連接,最好別太大 s.accept() ? ? #等待并接受客戶端的連接,返回新的套接字對(duì)象和(host,port)元祖
2).客戶端函數(shù)
s.connect((host,port)) #建立與服務(wù)器的連接,以(host,port)的元祖形式 s.connect_ex((host,port)) #和上面的功能差不多,只是出錯(cuò)了不拋異常,只是返回出錯(cuò)碼
3).通用函數(shù)
s.recv(size,flag) ? ? ? #接收最多size個(gè)大小的數(shù)據(jù),flag可以忽略,返回值為數(shù)據(jù)是字符串形式 s.send(str,flag) ? ? ? ?#發(fā)送str數(shù)據(jù),返回值是要發(fā)送的字節(jié)數(shù)量,可能數(shù)據(jù)未全部發(fā)送 s.sendall(str,flag) ? ? #發(fā)送全部str數(shù)據(jù),成功返回None,失敗則拋出異常 s.recv(size,flag) ? ? ? #接受最多size個(gè)數(shù)據(jù),并以字符串形式返回 s.recvfrom(str,flag) ? ?#與recv相同,但是返回值是(接收數(shù)據(jù)的字符串,發(fā)送數(shù)據(jù)的套接字地址)的元祖形式 s.sendto(str,flag,address) #連接到當(dāng)前套接字的遠(yuǎn)程地址。返回值是發(fā)送的字節(jié)數(shù),主要用于UDP s.getpeername() ? ? #返回連接套接字的遠(yuǎn)程地址。返回值通常是元組(host,port) s.getsockname() ? ? #返回套接字自己的地址。通常是一個(gè)元組(host,port) s.setsockopt(level,optname,value) # 設(shè)置給定套接字選項(xiàng)的值。 #假如端口被socket使用過,并且利用socket.close()來關(guān)閉連接,但此時(shí)端口還沒有釋放,要經(jīng)過TIME_WAIT的過程之后才能使用;為了實(shí)現(xiàn)端口的馬上復(fù)用,可以選擇setsocket()函數(shù)來達(dá)到目的。 #level:選項(xiàng)定義的層次。支持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6。 #optname:需設(shè)置的選項(xiàng)。SO_REUSEADDR SO_REUSEPORT #value:設(shè)置選項(xiàng)的值。 s.getsockopt(level,optname,buflen) #返回套接字選項(xiàng)的值。buflen:緩存長(zhǎng)度 s.settimeout(time) ?#設(shè)置socket連接超時(shí)時(shí)間,單位為秒,超時(shí)一般在剛創(chuàng)建套接字時(shí)設(shè)置 s.gettimeout() ? ? ?#返回當(dāng)前超時(shí)的時(shí)間,單位是秒,如果沒有設(shè)置超時(shí),則返回None。 s.close() ? ? ? ? ? #關(guān)閉套接字 s.fileno() ? ? ? ? ?#套接字的文件描述符 s.shutdown(how) ? ? # 關(guān)閉連接一邊或兩邊 s.setblocking(bool) #是否阻塞(默認(rèn)True),如果設(shè)置False,那么accept和recv時(shí)一旦無(wú)數(shù)據(jù),則報(bào)錯(cuò)。 s.makefile() ? ? ? ?#創(chuàng)建一個(gè)與該套接字相關(guān)聯(lián)的文件
5.一個(gè)簡(jiǎn)單的客戶端與服務(wù)端交互
Server.py
import socket? s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) ? ? ? ? ? ? # 創(chuàng)建socket對(duì)象 s.bind(('127.0.0.1',4323)) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 綁定地址 s.listen(5) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 建立5個(gè)監(jiān)聽 while True: ? ? conn,addr= s.accept() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 等待客戶端連接 ? ? print('歡迎{}'.format(addr)) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#打印訪問的用戶信息 ? ? while True: ? ? ? ? data=conn.recv(1024)? ? ? ? ? dt=data.decode('utf-8') ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #接收一個(gè)1024字節(jié)的數(shù)據(jù)? ? ? ? ? print('收到:',dt) ? ? ? ? aa=input('服務(wù)器發(fā)出:')? ? ? ? ? if aa=='quit': ? ? ? ? ? ? conn.close() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#關(guān)閉來自客戶端的連接 ? ? ? ? ? ? s.close() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #關(guān)閉服務(wù)器端連接 ? ? ? ? else: ? ? ? ? ? ? conn.send(aa.encode('utf-8')) ? ? ? ? ? ? ? ? ? ? ? #發(fā)送數(shù)據(jù)
Client.py
import socket ?? import sys c=socket.socket() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 創(chuàng)建socket對(duì)象 c.connect(('127.0.0.1',4323)) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#建立連接 while True: ? ? ab=input('客戶端發(fā)出:') ? ? if ab=='quit': ? ? ? ? c.close() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #關(guān)閉客戶端連接 ? ? ? ? sys.exit(0) ? ? else: ? ? ? ? c.send(ab.encode('utf-8')) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #發(fā)送數(shù)據(jù) ? ? ? ? data=c.recv(1024) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#接收一個(gè)1024字節(jié)的數(shù)據(jù) ? ? ? ? print('收到:',data.decode('utf-8')) ? ? ? ? ? ? ? ? ? ?#輸出接收的信息
可以看到我們實(shí)現(xiàn)了一個(gè)全雙工的Tcp/Ip聊天工具,對(duì)于服務(wù)器和客戶端來說,均可收發(fā)文件。
三、總結(jié)
Python中的socket編程難度不大,不過你要想寫好的Socket也不容易,希望本文能讓大家受益匪淺,畢竟小編可是把絕大多數(shù)經(jīng)常用到的Api的功能都展示了。
到此這篇關(guān)于Python Socket 編程知識(shí)點(diǎn)詳細(xì)介紹的文章就介紹到這了,更多相關(guān)Python Socket 編程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python matplotlib畫圖與中文設(shè)置操作實(shí)例分析
這篇文章主要介紹了Python matplotlib畫圖與中文設(shè)置操作,結(jié)合實(shí)例形式分析了Python使用matplotlib進(jìn)行圖形繪制及中文設(shè)置相關(guān)操作技巧,需要的朋友可以參考下2019-04-04Python 詳解爬取并統(tǒng)計(jì)CSDN全站熱榜標(biāo)題關(guān)鍵詞詞頻流程
讀萬(wàn)卷書不如行萬(wàn)里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Python爬取CSDN全站綜合熱榜標(biāo)題,順便統(tǒng)計(jì)關(guān)鍵詞詞頻,大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11Selenium+BeautifulSoup+json獲取Script標(biāo)簽內(nèi)的json數(shù)據(jù)
這篇文章主要介紹了Selenium+BeautifulSoup+json獲取Script標(biāo)簽內(nèi)的json數(shù)據(jù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Python制作簡(jiǎn)易注冊(cè)登錄系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Python簡(jiǎn)易注冊(cè)登錄系統(tǒng)的制作方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12Python的3種運(yùn)行方式:命令行窗口、Python解釋器、IDLE的實(shí)現(xiàn)
這篇文章主要介紹了Python的3種運(yùn)行方式:命令行窗口、Python解釋器、IDLE的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10python生成并處理uuid的實(shí)現(xiàn)方式
這篇文章主要介紹了python生成并處理uuid的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03