Python 之 Socket編程(TCP/UDP)

Python提供了兩個(gè)基本的scoket模塊分別是:
1.Socket : 它提供了標(biāo)準(zhǔn)的 BSD Sockets API。

  1. 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ù)通信跛璧。

Socket.jpg

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則是不可靠信道
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末放案,一起剝皮案震驚了整個(gè)濱河市姚建,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吱殉,老刑警劉巖掸冤,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件厘托,死亡現(xiàn)場離奇詭異,居然都是意外死亡稿湿,警方通過查閱死者的電腦和手機(jī)铅匹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來饺藤,“玉大人包斑,你說我怎么就攤上這事√樗祝” “怎么了罗丰?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長再姑。 經(jīng)常有香客問我丸卷,道長,這世上最難降的妖魔是什么询刹? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮萎坷,結(jié)果婚禮上凹联,老公的妹妹穿的比我還像新娘。我一直安慰自己哆档,他們只是感情好蔽挠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著瓜浸,像睡著了一般澳淑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上插佛,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天杠巡,我揣著相機(jī)與錄音,去河邊找鬼雇寇。 笑死氢拥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的锨侯。 我是一名探鬼主播嫩海,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼囚痴!你這毒婦竟也來了叁怪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤深滚,失蹤者是張志新(化名)和其女友劉穎奕谭,沒想到半個(gè)月后涣觉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡展箱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年旨枯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片混驰。...
    茶點(diǎn)故事閱讀 39,773評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡攀隔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出栖榨,到底是詐尸還是另有隱情昆汹,我是刑警寧澤,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布婴栽,位于F島的核電站满粗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏愚争。R本人自食惡果不足惜映皆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望轰枝。 院中可真熱鬧捅彻,春花似錦、人聲如沸鞍陨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诚撵。三九已至缭裆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間寿烟,已是汗流浹背澈驼。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留韧衣,地道東北人盅藻。 一個(gè)月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像畅铭,于是被迫代替她去往敵國和親氏淑。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容