Python提供了兩個(gè)基本的scoket模塊分別是:
1.Socket : 它提供了標(biāo)準(zhǔn)的 BSD Sockets API。
- SocketServer :它提供了服務(wù)器中心類片吊,可以簡化網(wǎng)絡(luò)服務(wù)器的開發(fā)绽昏。
下面講的是Socket模塊功能
一 . Socket 類型
1 . 套接字格式:
socket(family,type[,protocal]) 使用給定的地址族、套接字類型俏脊、協(xié)議編號(默認(rèn)為0)來創(chuàng)建套接字全谤。
socket類型 | 描述 |
---|---|
socket.AF_UNIX | 只能夠用于單一的Unix系統(tǒng)進(jìn)程間通信 |
socket.AF_INET | 服務(wù)器之間網(wǎng)絡(luò)通信 |
socket.AF_INET6 | IPv6 |
socket.SOCK_STREAM | 流式socket , for TCP |
socket.SOCK_DGRAM | 數(shù)據(jù)報(bào)式socket , for UDP |
socket.SOCK_RAW | 原始套接字,普通的套接字無法處理ICMP爷贫、IGMP等網(wǎng)絡(luò)報(bào)文认然,而SOCK_RAW可以;其次漫萄,SOCK_RAW也可以處理特殊的IPv4報(bào)文卷员;此外,利用原始套接字腾务,可以通過IP_HDRINCL套接字選項(xiàng)由用戶構(gòu)造IP頭毕骡。 |
socket.SOCK_SEQPACKET | 可靠的連續(xù)數(shù)據(jù)包服務(wù) |
創(chuàng)建TCP Socket: | s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) |
創(chuàng)建UDP Socket: | s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) |
2 . 套接字地址: 主機(jī)-端口對
有效的端口號: 0~ 65535
但是小于1024的端口號基本上都預(yù)留給了操作系統(tǒng)
POSIX兼容系統(tǒng)(如Linux、Mac OS X等),在/etc/services文件中找到這些預(yù)留端口與的列表
3. 面向連接的套接字
面向連接的通信提供序列化未巫、可靠的和不重復(fù)的數(shù)據(jù)交付窿撬,而沒有記錄邊界。意味著每條消息都可以拆分多個(gè)片段叙凡,并且每個(gè)消息片段都能到達(dá)目的地劈伴,然后將它們按順序組合在一起,最后將完整的信息傳遞給等待的應(yīng)用程序。
實(shí)現(xiàn)方式(TCP):
傳輸控制協(xié)議(TCP)握爷, 創(chuàng)建TCP必須使用SOCK_STREAM作為套接字類型
因?yàn)檫@些套接字(AF_INET)的網(wǎng)絡(luò)版本使用因特網(wǎng)協(xié)議(IP)來搜尋網(wǎng)絡(luò)中的IP,
所以整個(gè)系統(tǒng)通常結(jié)合這兩種協(xié)議(TCP/IP)來進(jìn)行網(wǎng)絡(luò)間數(shù)據(jù)通信跛璧。
4 . 面向無連接的套接字
數(shù)據(jù)報(bào)類型的套接字, 即在通信開始之前并不需要建議連接,當(dāng)然也無法保證它的順序性、可靠性或重復(fù)性
實(shí)現(xiàn)方式(UDP)
用戶數(shù)據(jù)包協(xié)議(UDP), 創(chuàng)建UDP必須使用SOCK_DGRAM (datagram)作為套接字類型
它也使用因特網(wǎng)來尋找網(wǎng)絡(luò)中主機(jī)饼拍,所以是UDP和IP的組合名字UDP/IP
二 . Socket 函數(shù)
注意點(diǎn):
1)TCP發(fā)送數(shù)據(jù)時(shí)赡模,已建立好TCP連接,所以不需要指定地址师抄。UDP是面向無連接的漓柑,每次發(fā)送要指定是發(fā)給誰。
2)服務(wù)端與客戶端不能直接發(fā)送列表叨吮,元組辆布,字典。需要字符串化repr(data)茶鉴。
類型 | socket函數(shù) | 描述 |
---|---|---|
服務(wù)端socket函數(shù) | s.bind(address) | 將套接字綁定到地址, 在AF_INET下,以元組(host,port)的形式表示地址. |
服務(wù)端socket函數(shù) | s.listen(backlog) | 開始監(jiān)聽TCP傳入連接锋玲。backlog指定在拒絕連接之前,操作系統(tǒng)可以掛起的最大連接數(shù)量涵叮。該值至少為1惭蹂,大部分應(yīng)用程序設(shè)為5就可以了。 |
服務(wù)端socket函數(shù) | s.accept() | 接受TCP連接并返回(conn,address),其中conn是新的套接字對象割粮,可以用來接收和發(fā)送數(shù)據(jù)盾碗。address是連接客戶端的地址。 |
客戶端socket函數(shù) | s.connect(address) | 連接到address處的套接字舀瓢。一般address的格式為元組(hostname,port)廷雅,如果連接出錯(cuò),返回socket.error錯(cuò)誤京髓。 |
客戶端socket函數(shù) | s.connect_ex(adddress) | 功能與connect(address)相同航缀,但是成功返回0,失敗返回errno的值堰怨。 |
公共socket函數(shù) | s.recv(bufsize[,flag]) | 接受TCP套接字的數(shù)據(jù)芥玉。數(shù)據(jù)以字符串形式返回,bufsize指定要接收的最大數(shù)據(jù)量备图。flag提供有關(guān)消息的其他信息飞傀,通郴市停可以忽略。 |
公共socket函數(shù) | s.send(string[,flag]) | 發(fā)送TCP數(shù)據(jù)砸烦。將string中的數(shù)據(jù)發(fā)送到連接的套接字。返回值是要發(fā)送的字節(jié)數(shù)量绞吁,該數(shù)量可能小于string的字節(jié)大小幢痘。 |
公共socket函數(shù) | s.sendall(string[,flag]) | 完整發(fā)送TCP數(shù)據(jù)。將string中的數(shù)據(jù)發(fā)送到連接的套接字家破,但在返回之前會(huì)嘗試發(fā)送所有數(shù)據(jù)颜说。成功返回None,失敗則拋出異常汰聋。 |
公共socket函數(shù) | s.recvfrom(bufsize[.flag]) | 接受UDP套接字的數(shù)據(jù)门粪。與recv()類似,但返回值是(data,address)烹困。其中data是包含接收數(shù)據(jù)的字符串玄妈,address是發(fā)送數(shù)據(jù)的套接字地址。 |
公共socket函數(shù) | s.sendto(string[,flag],address) | 發(fā)送UDP數(shù)據(jù)髓梅。將數(shù)據(jù)發(fā)送到套接字拟蜻,address是形式為(ipaddr,port)的元組枯饿,指定遠(yuǎn)程地址酝锅。返回值是發(fā)送的字節(jié)數(shù)。 |
公共socket函數(shù) | s.close() | 關(guān)閉套接字奢方。 |
公共socket函數(shù) | s.getpeername() | 返回連接套接字的遠(yuǎn)程地址搔扁。返回值通常是元組(ipaddr,port)。 |
公共socket函數(shù) | s.getsockname() | 返回套接字自己的地址蟋字。通常是一個(gè)元組(ipaddr,port) |
公共socket函數(shù) | s.setsockopt(level,optname,value) | 設(shè)置給定套接字選項(xiàng)的值稿蹲。 |
公共socket函數(shù) | s.getsockopt(level,optname[.buflen]) | 返回套接字選項(xiàng)的值。 |
公共socket函數(shù) | s.settimeout(timeout) | 設(shè)置套接字操作的超時(shí)期愉老,timeout是一個(gè)浮點(diǎn)數(shù)场绿,單位是秒。值為None表示沒有超時(shí)期嫉入。一般焰盗,超時(shí)期應(yīng)該在剛創(chuàng)建套接字時(shí)設(shè)置,因?yàn)樗鼈兛赡苡糜谶B接的操作(如connect()) |
公共socket函數(shù) | s.gettimeout() | 返回當(dāng)前超時(shí)期的值咒林,單位是秒熬拒,如果沒有設(shè)置超時(shí)期,則返回None垫竞。 |
公共socket函數(shù) | s.fileno() | 返回套接字的文件描述符澎粟。 |
公共socket函數(shù) | s.setblocking(flag) | 如果flag為0蛀序,則將套接字設(shè)為非阻塞模式,否則將套接字設(shè)為阻塞模式(默認(rèn)值)活烙。非阻塞模式下徐裸,如果調(diào)用recv()沒有發(fā)現(xiàn)任何數(shù)據(jù),或send()調(diào)用無法立即發(fā)送數(shù)據(jù)啸盏,那么將引起socket.error異常重贺。 |
公共socket函數(shù) | s.makefile() | 創(chuàng)建一個(gè)與該套接字相關(guān)連的文件 |
三 . socket編程思路
1. TCP編程(點(diǎn)對點(diǎn))
TCP服務(wù)端:
1 創(chuàng)建套接字,綁定套接字到本地IP與端口
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind()
2 開始監(jiān)聽連接
s.listen()
3 進(jìn)入循環(huán)回懦,不斷接受客戶端的連接請求 s.accept()
4 然后接收傳來的數(shù)據(jù)气笙,并發(fā)送給對方數(shù)據(jù)
s.recv() , s.sendall()
5 傳輸完畢后,關(guān)閉套接字
s.close()TCP客戶端:
1 創(chuàng)建套接字怯晕,連接遠(yuǎn)端地址
socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.connect()
2 連接后發(fā)送數(shù)據(jù)和接收數(shù)據(jù) # s.sendall(), s.recv()
3 傳輸完畢后潜圃,關(guān)閉套接字
s.close()-
簡單的demo
- 服務(wù)端
import socket # 導(dǎo)入 socket 模塊
s = socket.socket() # 創(chuàng)建 socket 對象
host = socket.gethostname() # 獲取本地主機(jī)名
port = 12346 # 設(shè)置端口
s.bind((host, port)) # 綁定端口
s.listen(5) # 等待客戶端連接
while True:
c, addr = s.accept() # 建立客戶端連接。
print('連接地址:', addr)
c.send('歡迎訪問菜鳥教程舟茶!')
c.close() # 關(guān)閉連接
- 客戶端:
import socket # 導(dǎo)入 socket 模塊
s = socket.socket() # 創(chuàng)建 socket 對象
host = socket.gethostname() # 獲取本地主機(jī)名
port = 12345 # 設(shè)置端口好
s.connect((host, port))
print(s.recv(1024))
s.close()
2 . UDP編程(廣播)
- 服務(wù)端
from socket import *
HOST = '192.168.1.60'
PORT = 9999
s = socket(AF_INET, SOCK_DGRAM)
s.connect((HOST, PORT))
while True:
message = input('send message:>>')
s.sendall(message)
data = s.recv(1024)
print(data)
s.close()
四 . TCP和UDP的優(yōu)缺點(diǎn)及區(qū)別
1 . TCP的優(yōu)點(diǎn)缺點(diǎn):
TCP的優(yōu)點(diǎn):可靠谭期,穩(wěn)定 TCP的可靠體現(xiàn)在TCP在傳遞數(shù)據(jù)之前,會(huì)有三次握手來建立連接稚晚,而且在數(shù)據(jù)傳遞時(shí)崇堵,有確認(rèn)、窗口客燕、重傳鸳劳、擁塞控制機(jī)制,在數(shù)據(jù)傳完后也搓,還會(huì)斷開連接用來節(jié)約系統(tǒng)資源赏廓。
TCP的缺點(diǎn): 慢,效率低傍妒,占用系統(tǒng)資源高幔摸,易被攻擊 TCP在傳遞數(shù)據(jù)之前,要先建連接颤练,這會(huì)消耗時(shí)間既忆,而且在數(shù)據(jù)傳遞時(shí),確認(rèn)機(jī)制嗦玖、重傳機(jī)制患雇、擁塞控制機(jī)制等都會(huì)消耗大量的時(shí)間,而且要在每臺(tái)設(shè)備上維護(hù)所有的傳輸連接宇挫,事實(shí)上苛吱,每個(gè)連接都會(huì)占用系統(tǒng)的CPU、內(nèi)存等硬件資源器瘪。 而且翠储,因?yàn)門CP有確認(rèn)機(jī)制绘雁、三次握手機(jī)制,這些也導(dǎo)致TCP容易被人利用援所,實(shí)現(xiàn)DOS庐舟、DDOS、CC等攻擊任斋。
什么時(shí)候應(yīng)該使用TCP : 當(dāng)對網(wǎng)絡(luò)通訊質(zhì)量有要求的時(shí)候继阻,比如:整個(gè)數(shù)據(jù)要準(zhǔn)確無誤的傳遞給對方,這往往用于一些要求可靠的應(yīng)用废酷,比如HTTP、HTTPS抹缕、FTP等傳輸文件的協(xié)議澈蟆,POP、SMTP等郵件傳輸?shù)膮f(xié)議卓研。 在日常生活中趴俘,常見使用TCP協(xié)議的應(yīng)用如下: 瀏覽器,用的HTTP FlashFXP奏赘,用的FTP Outlook寥闪,用的POP、SMTP Putty磨淌,用的Telnet疲憋、SSH QQ文件傳輸.
2 . TCP的優(yōu)點(diǎn)缺點(diǎn):
UDP的優(yōu)點(diǎn): 快,比TCP稍安全 UDP沒有TCP的握手梁只、確認(rèn)缚柳、窗口、重傳搪锣、擁塞控制等機(jī)制秋忙,UDP是一個(gè)無狀態(tài)的傳輸協(xié)議,所以它在傳遞數(shù)據(jù)時(shí)非彻怪郏快灰追。沒有TCP的這些機(jī)制,UDP較TCP被攻擊者利用的漏洞就要少一些狗超。但UDP也是無法避免攻擊的弹澎,比如:UDP Flood攻擊……
UDP的缺點(diǎn): 不可靠,不穩(wěn)定 因?yàn)閁DP沒有TCP那些可靠的機(jī)制抡谐,在數(shù)據(jù)傳遞時(shí)裁奇,如果網(wǎng)絡(luò)質(zhì)量不好,就會(huì)很容易丟包麦撵。
什么時(shí)候應(yīng)該使用UDP:當(dāng)對網(wǎng)絡(luò)通訊質(zhì)量要求不高的時(shí)候刽肠,要求網(wǎng)絡(luò)通訊速度能盡量的快溃肪,這時(shí)就可以使用UDP。 比如音五,日常生活中惫撰,常見使用UDP協(xié)議的應(yīng)用如下: QQ語音 QQ視頻 TFTP ……
3 . TCP與UDP的區(qū)別
- tcp協(xié)議和udp協(xié)議的差別
1.基于連接與無連接;
2.對系統(tǒng)資源的要求(TCP較多躺涝,UDP少)厨钻;
3.UDP程序結(jié)構(gòu)較簡單;
4.流模式與數(shù)據(jù)報(bào)模式 坚嗜;
5.TCP保證數(shù)據(jù)正確性夯膀,UDP可能丟包,TCP保證數(shù)據(jù)順序苍蔬,UDP不保證诱建。
TCP | UDP | |
---|---|---|
是否連接 | 面向連接 | 面向非連接 |
傳輸可靠性 | 可靠 | 不可靠 |
應(yīng)用場合 | 傳輸大量數(shù)據(jù) | 少量數(shù)據(jù) |
速度 | 慢 | 快 |
- TCP與UDP區(qū)別總結(jié):
1、TCP面向連接(如打電話要先撥號建立連接);UDP是無連接的碟绑,即發(fā)送數(shù)據(jù)之前不需要建立連接
2俺猿、TCP提供可靠的服務(wù)。也就是說格仲,通過TCP連接傳送的數(shù)據(jù)押袍,無差錯(cuò),不丟失凯肋,不重復(fù)谊惭,且按序到達(dá);UDP盡最大努力交付,即不保證可靠交付
3否过、TCP面向字節(jié)流午笛,實(shí)際上是TCP把數(shù)據(jù)看成一連串無結(jié)構(gòu)的字節(jié)流;UDP是面向報(bào)文的UDP沒有擁塞控制,因此網(wǎng)絡(luò)出現(xiàn)擁塞不會(huì)使源主機(jī)的發(fā)送速率降低(對實(shí)時(shí)應(yīng)用很有用苗桂,如IP電話药磺,實(shí)時(shí)視頻會(huì)議等)
4、每一條TCP連接只能是點(diǎn)到點(diǎn)的;UDP支持一對一煤伟,一對多癌佩,多對一和多對多的交互通信
5、TCP首部開銷20字節(jié);UDP的首部開銷小便锨,只有8個(gè)字節(jié)
6围辙、TCP的邏輯通信信道是全雙工的可靠信道,UDP則是不可靠信道