即C/S架構(gòu),其實(shí)web服務(wù)在某種意義上也算是C/S架構(gòu)
一個(gè)特點(diǎn)是服務(wù)器端持續(xù)運(yùn)行對(duì)外提供服務(wù)
為何學(xué)習(xí)socket一定要先學(xué)習(xí)互聯(lián)網(wǎng)協(xié)議:
C/S架構(gòu)的軟件是基于網(wǎng)絡(luò)進(jìn)行通信的
網(wǎng)絡(luò)的核心就是一堆協(xié)議,即標(biāo)準(zhǔn),想要開發(fā)一款基于網(wǎng)絡(luò)通信的軟件就必須遵循這些標(biāo)準(zhǔn)
socket是處在應(yīng)用層和傳輸層中間的一組接口
說到這,那么socket到底是個(gè)什么呢?Socket是應(yīng)用層與TCP/IP協(xié)議族通信的中間軟件抽象層,它是一組接口。在設(shè)計(jì)模式中,socket其實(shí)就是一個(gè)門面模式,它把復(fù)雜的TCP/IP協(xié)議族隱藏在socket接口后面,對(duì)用戶來說,一組簡單的接口就是全部,讓socket去組織數(shù)據(jù),以符合指定的協(xié)議。所以,無需深究TCP/UDP協(xié)議,socket已經(jīng)為我們封裝好了
基于文件類型的套接字家族:AFUNIX基于網(wǎng)絡(luò)類型的套接字家族:AFINET
先從服務(wù)器端說起。服務(wù)器端先初始化Socket,然后與端口綁定(bind),對(duì)端口進(jìn)行監(jiān)聽(listen),調(diào)用accept阻塞,等待客戶端連接。在這時(shí)如果有個(gè)客戶端初始化一個(gè)Socket,然后連接服務(wù)器(connect),如果連接成功,這時(shí)客戶端與服務(wù)器端的連接就建立了??蛻舳税l(fā)送數(shù)據(jù)請(qǐng)求,服務(wù)器端接收請(qǐng)求并處理請(qǐng)求,然后把回應(yīng)數(shù)據(jù)發(fā)送給客戶端,客戶端讀取數(shù)據(jù),最后關(guān)閉連接,一次交互結(jié)束
服務(wù)端套接字函數(shù)
s.bind() 綁定(主機(jī),端口號(hào))到套接字
s.listen() 開始TCP監(jiān)聽
s.accept() 被動(dòng)接受TCP客戶的連接,(阻塞式)等待連接的到來
客戶端套接字函數(shù)
s.connect() 主動(dòng)初始化TCP服務(wù)器連接
s.connect_ex() connect()函數(shù)的擴(kuò)展版本,出錯(cuò)時(shí)返回出錯(cuò)碼,而不是拋出異常
公共用途的套接字函數(shù)
s.recv() 接收TCP數(shù)據(jù)
s.send() 發(fā)送TCP數(shù)據(jù)(send在待發(fā)送數(shù)據(jù)量大于己端緩存區(qū)剩余空間時(shí),數(shù)據(jù)丟失,不會(huì)發(fā)完)
s.sendall() 發(fā)送完整的TCP數(shù)據(jù)(本質(zhì)就是循環(huán)調(diào)用send,sendall在待發(fā)送數(shù)據(jù)量大于己端緩存區(qū)剩余空間時(shí),數(shù)據(jù)不丟失,循環(huán)調(diào)用send直到發(fā)完)
s.recvfrom() 接收UDP數(shù)據(jù)
s.sendto() 發(fā)送UDP數(shù)據(jù)
s.getpeername() 連接到當(dāng)前套接字的遠(yuǎn)端的地址
s.getsockname() 當(dāng)前套接字的地址
s.getsockopt() 返回指定套接字的參數(shù)
s.setsockopt() 設(shè)置指定套接字的參數(shù)
s.close() 關(guān)閉套接字
面向鎖的套接字方法
s.setblocking() 設(shè)置套接字的阻塞與非阻塞模式
s.settimeout() 設(shè)置阻塞套接字操作的超時(shí)時(shí)間
s.gettimeout() 得到阻塞套接字操作的超時(shí)時(shí)間
面向文件的套接字的函數(shù)
s.fileno() 套接字的文件描述符
s.makefile() 創(chuàng)建一個(gè)與該套接字相關(guān)的文件
代碼示例:
服務(wù)端
from socket import *
phone=socket(AF_INET,SOCK_STREAM)
phone.bind(('127.0.0.1',8081))
phone.listen(5)
conn,addr=phone.accept()
while True:
data=conn.recv(1024)
print('server===>')
print(data)
conn.send(data.upper())
conn.close()
phone.close()
客戶端
from socket import *
phone=socket(AF_INET,SOCK_STREAM)
phone.connect(('127.0.0.1',8081))
while True:
msg=input('>>: ').strip()
phone.send(msg.encode('utf-8'))
print('client====>')
data=phone.recv(1024)
print(data)
注意:這時(shí)候當(dāng)客戶端輸入消息為空的話程序會(huì)卡住,那是因?yàn)闊o論是服務(wù)端還是客戶端都要到自己所在主機(jī)緩沖區(qū)去拿消息,因?yàn)檫@時(shí)發(fā)送為空,服務(wù)端根本就不會(huì)有任何反應(yīng),所以客戶端的緩沖區(qū)也不會(huì)有任何內(nèi)容,所以這時(shí)它會(huì)一直徒勞的等待。。。
這時(shí)的解決辦法當(dāng)然要在客戶端想辦法,很簡單,我們不讓客戶端發(fā)送空消息即可,在send()方法之前加判斷:
if not msg :continue
你肯定以為這個(gè)時(shí)候就完事了,這時(shí)請(qǐng)嘗試斷開客戶端鏈接試試。。。試想,既然作為服務(wù)端,顧名思義就是要持續(xù)不斷的為不同的客戶端持續(xù)的提供服務(wù),怎么能一個(gè)客戶端用完即結(jié)束呢?解決方案如下:
while True: #鏈接循環(huán)
conn,addr=phone.accept()
print('電話線路是',conn)
print('客戶端的手機(jī)號(hào)是',addr)
while True: #通信循環(huán)
try:
data=conn.recv(1024)
if not data:break
print('客戶端發(fā)來的消息是',data)
conn.send(data.upper())
except Exception:
break
conn.close()
phone.close()
注意:可能會(huì)有人遇到重啟服務(wù)端時(shí)Address already in use 的情況,這個(gè)是由于你的服務(wù)端仍然存在四次揮手的timewait狀態(tài)在占用地址(如果不懂,請(qǐng)深入研究1.tcp三次握手,四次揮手 2.syn洪水*** 3.服務(wù)器高并發(fā)情況下會(huì)有大量的timewait狀態(tài)的優(yōu)化方法)
解決方法:
#加入一條socket配置,重用ip和端口
phone=socket(AF_INET,SOCK_STREAM)
phone.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #就是它,在bind前加
phone.bind(('127.0.0.1',8080))
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
文章標(biāo)題:Socket網(wǎng)絡(luò)編程初探-創(chuàng)新互聯(lián)
網(wǎng)頁網(wǎng)址:http://www.rwnh.cn/article40/dghheo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、全網(wǎng)營銷推廣、網(wǎng)站制作、網(wǎng)站策劃、網(wǎng)站營銷、App開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容