Python 網(wǎng)絡(luò)編程(二)

注:需要了解網(wǎng)絡(luò)編程基本概念的讀者钝荡,可以閱讀小編的 Python網(wǎng)絡(luò)編程(一)

Python 網(wǎng)絡(luò)編程(一)的最后介紹了傳輸層的兩個協(xié)議:TCP & UDP督函。TCP提供面向連接的可靠的傳輸層服務(wù)锹锰,創(chuàng)建連接時三次握手朋截,斷開連接時四次揮手嚎朽;UDP提供無連接的不可靠的傳輸層服務(wù)逾苫,適用于對實時性要求較高卿城,可靠性較低的網(wǎng)絡(luò)傳輸情況,如視頻傳輸铅搓。

1.TCP網(wǎng)絡(luò)編程實現(xiàn)
1)服務(wù)端

①創(chuàng)建流式套接字
s = socket.socket(socket.AF_INIT,socket.SOCK_STREAM)
或者:
s = socket.socket()
備注:AF_INIT--->地址族協(xié)議類型:IPV4
SOCK_STREAM--->套接字類型:流式套接字
②綁定IP和端口
ADDR = ('IP地址',端口)
s.bind(ADDR)
③設(shè)置監(jiān)聽
s.listen(5)
將套接字設(shè)置為"監(jiān)聽套接字"瑟押,并設(shè)置"監(jiān)聽隊列"長度為5
④阻塞等待客戶端連接
connfd,addr = s.accept()
返回值:connfd--->用于和指定客戶端通信的新套接字;addr--->連接客戶端的IP
⑤消息收發(fā)
接收:data = connfd.recv(bufersize).decode()
發(fā)送:n = connfd.send(data.encode())
⑥關(guān)閉套接字:
connfd.close()
s.close()

服務(wù)端代碼實現(xiàn):

'''示意服務(wù)端
接收客戶端消息并打印
當(dāng)客戶端斷開與服務(wù)端的連接后星掰,recv立即結(jié)束阻塞勉耀,返回空字符串
'''
import socket
 
# 創(chuàng)建套流式接字
sockfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ADDR = ('127.0.0.1', 8888)
# 綁定IP和端口
sockfd.bind(ADDR)
# 設(shè)置監(jiān)聽
sockfd.listen(5)
 
while True:
    print('Waiting for Connection...')
    # 阻塞等待客戶端連接s
    connfd,addr = sockfd.accept()
    print('Connect to client:',addr)
    while True:
        # 接收
        data = connfd.recv(1024).decode()
        if not data:
            break
        print('Receive:',data)
        # 發(fā)送,send返回發(fā)送的字節(jié)數(shù)
        n = connfd.send('Receive your message!'.encode())
        print('feedback %d byte' % n )
    # 關(guān)閉套接字
    connfd.close()
# 關(guān)閉套接字
sockfd.close()

2)客戶端

  1. 無需綁定IP和端口蹋偏,端口由系統(tǒng)自動分配
  2. 無需設(shè)置監(jiān)聽
  3. 無需創(chuàng)建新的套接字

流程:
①創(chuàng)建流式套接字
②發(fā)起連接請求
ADDR = ('IP',端口)
s.connect(ADDR)
③消息收發(fā)
n = s.send(data.encode())
data = s.recv(bufersize).decode()
④關(guān)閉套接字
s.close()

客戶端代碼實現(xiàn):

'''示意客戶端
向服務(wù)端發(fā)送消息便斥,接收并打印服務(wù)端返回的消息
客戶端輸入空行或者'q'時請求與服務(wù)端斷開
'''
import socket
# 創(chuàng)建套流式接字
sockfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ADDR = ("127.0.0.1", 8888)
 
# 向服務(wù)端發(fā)起連接請求
sockfd.connect(ADDR)
 
while True:
    data = input("發(fā)送消息>>>") or 'q'
    if data == 'q':
        break
    # 發(fā)送
    sockfd.send(data.encode())
    # 接收
    back = sockfd.recv(1024)
    print(back.decode())
 
sockfd.close()

2.UDP網(wǎng)絡(luò)編程實現(xiàn)
1)服務(wù)端

①創(chuàng)建數(shù)據(jù)報套接字:
sockfd = socket(AF_INET,SOCK_DGRAM)
②綁定服務(wù)端地址(服務(wù)端須要有固定的IP和端口號):
ADDR = ('IP地址',端口)
sockfd.bind(ADDR)
③消息的收發(fā):
data,addr = sockfd.recvfrom(buffersize)
n = sockfd.sendto(data,ADDR)
④關(guān)閉套接字:
sockfd.close()

服務(wù)端代碼實現(xiàn):

'''UDP服務(wù)端
綁定命令行輸入的服務(wù)端地址
接收客戶端發(fā)送的消息,并返回
'''
import socket
import sys
# 判斷命令行參數(shù)個數(shù)
if len(sys.argv) < 3:
    print('''
            argv is error!!
            runs as
            python3 udp_client.py 127.0.0.1 8888
        ''')
    sys.exit(0)
 
HOST = sys.argv[1]
# 端口為整數(shù)
PORT = int(sys.argv[2])
# 服務(wù)端地址
ADDR = (HOST,PORT)
# 創(chuàng)建數(shù)據(jù)報套接字
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 綁定服務(wù)端地址
s.bind(ADDR)
 
while True:
        # 接收
        data,addr = s.recvfrom(1024)
        print("Receive from {} : {}".format(addr,data.decode()))
        # 發(fā)送
        s.sendto('Receive your message'.encode(),addr)
 
s.close()

2)客戶端

①創(chuàng)建套接字
sockfd = socket(AF_INET,SOCK_DGRAM)
②數(shù)據(jù)收發(fā)
data,addr = sockfd.recvfrom(bufersize).decode()
n = sockfd.sendto(data,ADDR)
③關(guān)閉套接字
sockfd.close()

客戶端代碼實現(xiàn):

'''UDP客戶端
向命令行輸入的服務(wù)端地址發(fā)送消息
同時接收該服務(wù)端發(fā)來的消息
'''
import socket
import sys
 
# 判斷命令行參數(shù)個數(shù)
if len(sys.argv) < 3:
    print('''
            argv is error!!
            runs as
            python3 udp_client.py 127.0.0.1 8888
        ''')
    sys.exit(0)
 
HOST = sys.argv[1]
# 端口為整數(shù)
PORT = int(sys.argv[2])
# 服務(wù)端地址
ADDR = (HOST,PORT)
# 創(chuàng)建數(shù)據(jù)報套接字
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
 
while True:
    data = input("Send the message >>>") or 'q'
    if data == 'q':
        break
    # 發(fā)送
    s.sendto(data.encode(),ADDR)
    # 接收
    r_data,addr = s.recvfrom(1024)
    print(r_data.decode())
 
# 關(guān)閉套接字
s.close()

3.相關(guān)概念
1) 網(wǎng)絡(luò)收發(fā)緩沖區(qū):
緩沖區(qū)的功能:①協(xié)調(diào)讀寫速度威始,②減少和磁盤的交互
recv和send實際上是從緩沖區(qū)獲取內(nèi)容枢纠,向緩沖區(qū)發(fā)送內(nèi)容

2) TCP粘包:
原因:TCP采用字節(jié)流的方式,消息之間沒有邊界黎棠,如果發(fā)送和接收速度不匹配晋渺,會造成多次發(fā)送的內(nèi)容被一次接收,形成意義上的誤解即粘包脓斩。
條件:當(dāng)使用send快速的連續(xù)發(fā)送極有可能產(chǎn)生粘包
如何處理:
①發(fā)送時添加結(jié)束位標志木西,接收端通過標志進行判斷
②發(fā)送一個數(shù)據(jù)結(jié)構(gòu)
③當(dāng)連續(xù)發(fā)送時每次發(fā)送有一個短暫延遲 sleep(0.1)

3) 'TCP流式套接字'和'UDP數(shù)據(jù)報套接字'的區(qū)別
①TCP傳輸數(shù)據(jù)使用字節(jié)流的方式傳輸,UDP是數(shù)據(jù)報,因此TCP會產(chǎn)生粘包現(xiàn)象随静。
②TCP對網(wǎng)絡(luò)條件要求高八千,UDP更適合實時傳輸
③TCP傳輸是建立在連接的基礎(chǔ)上,保證傳輸?shù)目煽啃粤敲停欢鳸DP一次接收一個數(shù)據(jù)報恋捆,不保證完整性
④TCP使用listen accept建立連接,udp不需要
⑤收發(fā)消息TCP使用recv和send重绷,UDP使用recvfrom和sendto

4.下節(jié)預(yù)告
Python 網(wǎng)絡(luò)編程(三)將為大家介紹TCP流式套接字的典型應(yīng)用:文件傳輸以及http網(wǎng)頁傳輸沸停;UDP的典型應(yīng)用:局域網(wǎng)發(fā)送廣播消息和接收廣播消息~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市昭卓,隨后出現(xiàn)的幾起案子愤钾,更是在濱河造成了極大的恐慌瘟滨,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件能颁,死亡現(xiàn)場離奇詭異室奏,居然都是意外死亡,警方通過查閱死者的電腦和手機劲装,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昌简,“玉大人占业,你說我怎么就攤上這事〈渴辏” “怎么了谦疾?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長犬金。 經(jīng)常有香客問我念恍,道長,這世上最難降的妖魔是什么晚顷? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任峰伙,我火速辦了婚禮,結(jié)果婚禮上该默,老公的妹妹穿的比我還像新娘瞳氓。我一直安慰自己,他們只是感情好栓袖,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布匣摘。 她就那樣靜靜地躺著,像睡著了一般裹刮。 火紅的嫁衣襯著肌膚如雪音榜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天捧弃,我揣著相機與錄音赠叼,去河邊找鬼。 笑死违霞,一個胖子當(dāng)著我的面吹牛梅割,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播葛家,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼户辞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了癞谒?” 一聲冷哼從身側(cè)響起底燎,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤刃榨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后双仍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體枢希,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年朱沃,在試婚紗的時候發(fā)現(xiàn)自己被綠了苞轿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡逗物,死狀恐怖搬卒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情翎卓,我是刑警寧澤契邀,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站失暴,受9級特大地震影響坯门,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜逗扒,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一古戴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧矩肩,春花似錦允瞧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至建炫,卻和暖如春畦韭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肛跌。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工艺配, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人衍慎。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓转唉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親稳捆。 傳聞我的和親對象是個殘疾皇子赠法,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

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