日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達者為師

網(wǎng)站首頁 編程語言 正文

Python?Socket?編程知識點詳細(xì)介紹_python

作者:Python進階者 ? 更新時間: 2022-04-26 編程語言

前言:

? ? Socket又稱為套接字,它是所有網(wǎng)絡(luò)通信的基礎(chǔ)。網(wǎng)絡(luò)通信其實就是進程間的通信,Socket主要是使用IP地址,協(xié)議,端口號來標(biāo)識一個進程。端口號的范圍為0~65535(用戶端口號一般大于1024),協(xié)議有很多種,一般我們經(jīng)常用到的就是TCP,IP,UDP。下面我們來詳細(xì)了解下Socket吧。

一、導(dǎo)入Socket模塊

因為要操作套接字,所以需要用到套接字模塊,系統(tǒng)中自帶的就很不錯,下面我們來導(dǎo)入:

import socket

二、Socket基本用法

1.建立一個簡單的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ù)報式Socket
socket.AF_UNIX ?#只能夠用于單一的Unix系統(tǒng)進程間通信
socket.AF_INET6 ?#只能夠用于IPv6通信
socket.SOCK_RAW ?#原始套接字,可以處理ICMP、ARP等網(wǎng)絡(luò)報文,其它的不行
socket.SOCK_SEQPACKET ?#可靠的連續(xù)數(shù)據(jù)包服務(wù)

2.協(xié)議對應(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更高級,可以自動解析不是數(shù)字的host地址,兼容IPv4和 IPv6
socket.create_connection(address=('localhost',4320),timeout=4,source_address=('localhost',4320)) ?#前后兩個端口號一定要是一致,不然會報錯


#構(gòu)建一對已連接的套接字對象,新創(chuàng)建的套接字都是不可繼承的
socket.socketpair(family=socket.AF_INET,type=socket.SOCK_STREAM,proto=0)


#從文件描述符獲取到socket連接對象
socket.fromfd(fd=ab.fileno(),family=socket.AF_INET,type=socket.SOCK_STREAM,proto=0)


#套接字對象的類型
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:
[(, , 6, '', ('127.0.0.1', 3453))]


#獲取主機名
socket.gethostname()
socket.getfqdn()
socket.getfqdn(socket.gethostname())


#將主機名轉(zhuǎn)化為IP地址
socket.gethostbyname('www.baidu.com') #不支持IPV6解析
socket.gethostbyname_ex('www.baidu.com') #返回三元組,(主機名,相同地址的其它可用主機名的列表,IPv4 地址列表)


#網(wǎng)絡(luò)ip地址
socket.gethostbyname(socket.getfqdn(socket.gethostname()))


#將ip地址轉(zhuǎn)化為主機名,返回三元組(主機名,相同地址的其它可用主機名的列表,IPv4地址列表),支持IPV4/IPV6
socket.gethostbyaddr('192.168.1.4')


#解析主機名或者IP地址
socket.getnameinfo(('192.168.1.4',5434),0)


#判斷是否支持IPV6
socket.has_ipv6


#返回服務(wù)所使用的端口號
socket.getservbyname('https','tcp') #第一個參數(shù)為服務(wù)協(xié)議:Https,Http;第二個為傳輸協(xié)議:Tcp Udp


#返回端口所對應(yīng)的服務(wù)
socket.getservbyport(443,'tcp')


#設(shè)置主機名(僅限于Unix)
socket.sethostname(name)


#返回網(wǎng)卡信息的列表(僅限于Unix)
socket.if_nameindex()


#32位字節(jié)存儲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個連接,最好別太大
s.accept() ? ? #等待并接受客戶端的連接,返回新的套接字對象和(host,port)元祖

2).客戶端函數(shù)

s.connect((host,port)) #建立與服務(wù)器的連接,以(host,port)的元祖形式
s.connect_ex((host,port)) #和上面的功能差不多,只是出錯了不拋異常,只是返回出錯碼

3).通用函數(shù)

s.recv(size,flag) ? ? ? #接收最多size個大小的數(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個數(shù)據(jù),并以字符串形式返回
s.recvfrom(str,flag) ? ?#與recv相同,但是返回值是(接收數(shù)據(jù)的字符串,發(fā)送數(shù)據(jù)的套接字地址)的元祖形式
s.sendto(str,flag,address) #連接到當(dāng)前套接字的遠程地址。返回值是發(fā)送的字節(jié)數(shù),主要用于UDP
s.getpeername() ? ? #返回連接套接字的遠程地址。返回值通常是元組(host,port)
s.getsockname() ? ? #返回套接字自己的地址。通常是一個元組(host,port)
s.setsockopt(level,optname,value) # 設(shè)置給定套接字選項的值。
#假如端口被socket使用過,并且利用socket.close()來關(guān)閉連接,但此時端口還沒有釋放,要經(jīng)過TIME_WAIT的過程之后才能使用;為了實現(xiàn)端口的馬上復(fù)用,可以選擇setsocket()函數(shù)來達到目的。
#level:選項定義的層次。支持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6。
#optname:需設(shè)置的選項。SO_REUSEADDR SO_REUSEPORT
#value:設(shè)置選項的值。
s.getsockopt(level,optname,buflen) #返回套接字選項的值。buflen:緩存長度
s.settimeout(time) ?#設(shè)置socket連接超時時間,單位為秒,超時一般在剛創(chuàng)建套接字時設(shè)置
s.gettimeout() ? ? ?#返回當(dāng)前超時的時間,單位是秒,如果沒有設(shè)置超時,則返回None。
s.close() ? ? ? ? ? #關(guān)閉套接字
s.fileno() ? ? ? ? ?#套接字的文件描述符
s.shutdown(how) ? ? # 關(guān)閉連接一邊或兩邊
s.setblocking(bool) #是否阻塞(默認(rèn)True),如果設(shè)置False,那么accept和recv時一旦無數(shù)據(jù),則報錯。
s.makefile() ? ? ? ?#創(chuàng)建一個與該套接字相關(guān)聯(lián)的文件

5.一個簡單的客戶端與服務(wù)端交互

Server.py

import socket?
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM) ? ? ? ? ? ? # 創(chuàng)建socket對象
s.bind(('127.0.0.1',4323)) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 綁定地址
s.listen(5) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 建立5個監(jiān)聽
while True:
? ? conn,addr= s.accept() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 等待客戶端連接
? ? print('歡迎{}'.format(addr)) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#打印訪問的用戶信息
? ? while True:
? ? ? ? data=conn.recv(1024)?
? ? ? ? dt=data.decode('utf-8') ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #接收一個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對象
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) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#接收一個1024字節(jié)的數(shù)據(jù)
? ? ? ? print('收到:',data.decode('utf-8')) ? ? ? ? ? ? ? ? ? ?#輸出接收的信息

可以看到我們實現(xiàn)了一個全雙工的Tcp/Ip聊天工具,對于服務(wù)器和客戶端來說,均可收發(fā)文件。

三、總結(jié)

? ? Python中的socket編程難度不大,不過你要想寫好的Socket也不容易,希望本文能讓大家受益匪淺,畢竟小編可是把絕大多數(shù)經(jīng)常用到的Api的功能都展示了。

原文鏈接:https://blog.51cto.com/u_13389043/5022940

欄目分類
最近更新