python10-socket

socket網(wǎng)絡(luò)編程

  • socket基于tcp酣藻、ip協(xié)議的工具
  • 所有的網(wǎng)絡(luò)通信都基于socket
    • wanghzh/p/5560787.html
    • wupeiqi/articles/5040823.html
  • 客戶端去訪問服務(wù)器:
    • TCP:三次握手
    • UDP:單向訪問
    • python支持unix系統(tǒng)進(jìn)程與進(jìn)程之間的通信

自己實(shí)現(xiàn)socket客戶端和服務(wù)端

socket服務(wù)端
import socket

sk = socket.socket()  # 服務(wù)器啟動(dòng),創(chuàng)建socket
ip_port = ('127.0.0.1', 9999)
sk.bind(ip_port)  # socket綁定ip和端口作為服務(wù)端
sk.listen(5)  # socket服務(wù)器支持連接等待的數(shù)量

while True:
    sock, addr = sk.accept()  # 阻塞等待客戶端訪問
    sock.sendall(bytes('已鏈接到服務(wù)器', encoding='utf-8'))
    print(type(sock))
    while True:
        try:
            byte_data = sock.recv(1024) # 客戶端如果斷開了,這里會報(bào)異常
            data = str(byte_data, encoding='utf-8')
            ret = '服務(wù)器:%s' % data
            sock.sendall(bytes(ret, encoding='utf-8'))
            if data == 'q':
                break
        except Exception as e:
            break
        else:
            pass
        finally:
            pass
socket客戶端
import socket

client = socket.socket()  # 創(chuàng)建socket
client.connect(('127.0.0.1', 9999,))  # socket去連接服務(wù)端
byte_data = client.recv(1024)
print(str(byte_data, encoding='utf-8'))
while True:
    inp = input()
    client.sendall(bytes(inp, encoding='utf-8'))
    byte_data = client.recv(1024)
    data = str(byte_data, encoding='utf-8')
    if data == '服務(wù)器:q':
        print('斷開連接')
        break
    else:
        print(data)
client.close()
  • socket.sendall()方法在python2.7中接收字符串,在python3.x中接收ude是字節(jié)

socket更多方法

  • wupeiqi/articles/5040823.html
sk = socket.socket(family=socket.AF_INET,type=socket.SOCK_DGRAM,proto=0)
# family:socket.AF_INET = IPv4(默認(rèn)) IPv6
# type:TCP協(xié)議
# proto:默認(rèn)為0
sk.bind((ip,port,)
# 服務(wù)端綁定IP和port
sk.listen(count)
# 開始監(jiān)聽,參數(shù)表示最多等待的數(shù)量,當(dāng)count == 2
# 一個(gè)客戶端連上了服務(wù)器,如果再有2個(gè)客戶端訪問,后面的2個(gè)會處于等待狀態(tài),當(dāng)再有客戶端訪問,超過count == 2的客戶端會報(bào)錯(cuò)
sk.setblocking(bool)
# 是否阻塞
# True:阻塞(默認(rèn))
# False:不阻塞,當(dāng)socket調(diào)用recv和accept時(shí)會報(bào)錯(cuò),以后會用到
sk.connect((ip,port,)
# 客戶端連接服務(wù)端
sk.connect_ex((ip,port,)
# 同上,只是如果連接上,則返回0,如果連不上,返回錯(cuò)誤碼
sk.close()
# 斷開連接
sk.recv(1024)
# 接收信息,參數(shù)表示一次最所接收多少個(gè)字節(jié)
sk.recvfrom(buffersize)
# 從哪里接收UPD用到
sk.send()
# 發(fā)送信息,2.7中接收字符串,3.x中接收字節(jié)
# send方法有個(gè)弊端,實(shí)際發(fā)送的數(shù)據(jù)會出現(xiàn)少于實(shí)質(zhì)傳入的數(shù)據(jù)
sk.sendall()
# 底層通過循環(huán)和send方法發(fā)送數(shù)據(jù),不會出現(xiàn)數(shù)據(jù)丟失
sk.sendto()
# 針對UDP
sk.settimeout()
# 設(shè)置超時(shí)
sk.getsocketname()
# 返回socket自己的地址
sk.getpeername()
# 返回socket連接遠(yuǎn)程的地址
sk.fileno()
# socket的文件描述(后面會用到)

socket實(shí)現(xiàn)文件上傳

  • 注意防止粘包問題
server
import socket

server = socket.socket()
server.bind(('127.0.0.1', 9999))
server.listen(5)
print('服務(wù)器啟動(dòng):\n>>>>>')

while True:
    conn,address = server.accept()
    print('獲取到客戶端訪問:ip:%s port:%s'%(address[0], address[1]))
    retStr = '文件上傳服務(wù)器,請發(fā)送文件名以及文件大小'
    conn.sendall(bytes(retStr, encoding='utf-8'))
    fileInfo = conn.recv(1024)
    fileInfo = str(fileInfo, encoding='utf-8')
    fileName, fileLength = fileInfo.split('&')
    print('獲取到文件名:%s 文件大谐晏搿:%s'%(fileName,fileLength))
    conn.sendall(bytes('接收成功',encoding='utf-8'))
    totalLength = int(fileLength)
    hasLoadSize = 0
    file = open(fileName, mode='wb')
    while True:
        if hasLoadSize >= totalLength:
            break
        data = conn.recv(1024)
        file.write(data)
client
import socket
import os
client = socket.socket()
client.connect(('127.0.0.1', 9999))

connectInfo = client.recv(1024)
connectInfo = str(connectInfo, encoding='utf-8')
print(connectInfo)
fileName = input('請輸入文件名\n>>> ')
fileLength = os.stat('dest_top_img.jpg').st_size
ret_msg = '%s&%s'%(fileName,fileLength)
client.sendall(bytes(ret_msg, encoding='utf-8'))
rec_msg = client.recv(1024)
print(str(rec_msg, encoding='utf-8'))
print(str(rec_msg, encoding='utf-8'))
with open('dest_top_img.jpg', mode='rb') as file:
    for line in file:
        client.sendall(line)
client.close()
  • 粘包原因:
    • 報(bào)錯(cuò):ImageNotLoaded(下載完后打不開文件)
    • 客戶端發(fā)送文件到服務(wù)端,需要依賴系統(tǒng)的緩沖區(qū)
    • 服務(wù)端接收客戶端發(fā)送的文件,需要到緩沖區(qū)取
    • 但是客戶端緩沖區(qū)什么時(shí)候發(fā)送是系統(tǒng)決定的,不可控,可能存在這種情況,當(dāng)發(fā)送文件名和文件大小給服務(wù)器的時(shí)候,數(shù)據(jù)存放在緩沖區(qū)還沒發(fā)送出直接發(fā)送文件內(nèi)容瓤檐,當(dāng)服務(wù)端獲取文件和文件大小的字段帶有一部分文件的內(nèi)容,這就導(dǎo)致需要發(fā)送的文件到服務(wù)器實(shí)際接收的時(shí)候不完整
    • 解決:發(fā)送文件名拾氓、大小和發(fā)送文件之間與服務(wù)器做一個(gè)響應(yīng)

socketserver模塊實(shí)現(xiàn)多并發(fā)

  • socket模塊不支持多并發(fā),服務(wù)端同一時(shí)刻只支持響應(yīng)一個(gè)客戶端請求
  • 處理并發(fā)有兩種方式:
    • IO多路復(fù)用

    • socketserver模塊:由python提供的另一個(gè)模塊,用于解決多并發(fā)訪問的問題

      • 內(nèi)部實(shí)現(xiàn):IO多路復(fù)用&多線程或多進(jìn)程并發(fā)操作
    • 實(shí)現(xiàn)步驟:

      • 創(chuàng)建類繼承:socketserver.BaseRequestHandler
      • 創(chuàng)建server,傳入ip端口和剛創(chuàng)建的類
      • 開啟服務(wù)
```
import socketserver

class MyServer(socketserver.BaseRequestHandler):
    def handle(self):
        print(self.request) # 客戶端的連接
        print(self.client_address) # 客戶端地址
        print(self.server) # 當(dāng)前服務(wù)器:server

if __name__ == '__main__':
    server = socketserver.ThreadingTCPServer(('127.0.0.1',9999),MyServer)
    server.serve_forever()
# <socket.socket fd=520, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 9999), raddr=('127.0.0.1', 4971)>
# ('127.0.0.1', 4971)
# <socketocketserver.ThreadingTCPServer object at 0x00FAB310>
```

```
import socket
client = socket.socket()
client.connect(('127.0.0.1',9999))
```

梳理

  • 對象中封裝對象
  • 面向?qū)ο蟮膬煞N特性
    • 裝飾器 + 方法
    • @property + 方法
  • python2.7繼承流程
    • 繼承object類(新式類):頂部最后
    • 未繼承object類(經(jīng)典類):一條道走到黑,深度優(yōu)先
  • python3.x繼承流程
    • 頂部最后
  • 抽象類和抽象方法(python中目前用的不多)
    • 約束
    • 接口(python沒有接口)
    • 抽象類+抽象方法
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末翘县,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子宏娄,更是在濱河造成了極大的恐慌,老刑警劉巖逮壁,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孵坚,死亡現(xiàn)場離奇詭異粮宛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)卖宠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門巍杈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人扛伍,你說我怎么就攤上這事筷畦。” “怎么了刺洒?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵鳖宾,是天一觀的道長。 經(jīng)常有香客問我逆航,道長鼎文,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任因俐,我火速辦了婚禮拇惋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抹剩。我一直安慰自己撑帖,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布澳眷。 她就那樣靜靜地躺著胡嘿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪钳踊。 梳的紋絲不亂的頭發(fā)上灶平,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機(jī)與錄音箍土,去河邊找鬼。 笑死罐监,一個(gè)胖子當(dāng)著我的面吹牛吴藻,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播弓柱,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼沟堡,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了矢空?” 一聲冷哼從身側(cè)響起航罗,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎屁药,沒想到半個(gè)月后粥血,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年复亏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了趾娃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,852評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡缔御,死狀恐怖抬闷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情耕突,我是刑警寧澤笤成,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站眷茁,受9級特大地震影響炕泳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蔼卡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一喊崖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雇逞,春花似錦荤懂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至掉蔬,卻和暖如春廊宪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背女轿。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工箭启, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人蛉迹。 一個(gè)月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓傅寡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親北救。 傳聞我的和親對象是個(gè)殘疾皇子荐操,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評論 2 361

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)珍策,斷路器托启,智...
    卡卡羅2017閱讀 134,715評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,321評論 25 707
  • 昨晚微信上有個(gè)東北的小姑娘失眠,她說大叔既然睡不著攘宙,一起談?wù)勅松鷨h屯耸。 我回她說:"男人和女人的人生觀差別太大拐迁,談不...
    令狐大蔥閱讀 293評論 0 0
  • 媽媽告訴我唠亚,八嬸可能活不了幾天了,子宮癌晚期持痰。當(dāng)我聽到這個(gè)消息的時(shí)候異常的震驚灶搜,我記得4月份回家的時(shí)候,她還好好的...
    向行閱讀 309評論 8 3
  • “活著是為了給過去的自己看的” 有時(shí)候突發(fā)奇想,我會想象著自己如果回到過去面對當(dāng)年那個(gè)為什么事都煩惱的自己患雏,會是怎...
    燈燈_閱讀 369評論 0 0