30.4. 企業(yè)級(jí)開發(fā)進(jìn)階2.4:服務(wù)端快捷開發(fā)

前面的內(nèi)容中已經(jīng)介紹了TCP編程和UDP編程實(shí)現(xiàn)網(wǎng)絡(luò)數(shù)據(jù)的通信和共享

我們可以看到客戶端程序的編寫相對(duì)容易灵汪,主需要連接服務(wù)端然后跟服務(wù)端進(jìn)行數(shù)據(jù)交互就OK了檀训。但是服務(wù)端的程序編寫較為復(fù)雜,如果考慮到數(shù)據(jù)的并發(fā)處理等各種問題识虚,就更加復(fù)雜難以操作了肢扯。

python提供了一個(gè)socketserver模塊,可以用于更加快捷的構(gòu)建我們需要的服務(wù)端環(huán)境

本節(jié)內(nèi)容

  1. socketserver模塊簡(jiǎn)介
  2. 常規(guī)模式服務(wù)端編程
  3. 并發(fā)模式服務(wù)端編程

1. socketserver模塊簡(jiǎn)介

  • socketserver是什么担锤?
    socketserver模塊時(shí)python提供的內(nèi)置的用于快捷開發(fā)服務(wù)端程序的一個(gè)服務(wù)器框架蔚晨,通過封裝大量實(shí)現(xiàn)的方式減少開發(fā)人員工作量的同時(shí)能快捷開發(fā)出具有較高質(zhì)量的服務(wù)端程序。

  • socketserver中提供了什么肛循?
    socketserver模塊主要包含的服務(wù)器類:TCPserver铭腕、UCPserver、ThreadingTCPserver多糠、ThreadingUDPserver累舷、ForkingTCPserver、ForkingUDPserver
    注意:上述TCP表示TCP服務(wù)端編程需要的服務(wù)類夹孔,UDP表示UDP編程需要的服務(wù)類被盈,包含Threading的表示多線程并發(fā)需要的服務(wù)類;包含F(xiàn)orking的表示多進(jìn)程并發(fā)需要的服務(wù)類
    關(guān)于多線程和多進(jìn)程搭伤,后面的章節(jié)中會(huì)詳細(xì)介紹

  • socketserver核心操作只怎?
    socketserver框架中,服務(wù)端的處理類主要有StreamRequestHandler(基于TCP協(xié)議的)怜俐、DatagramRequestHandler(基于UDP協(xié)議的)身堡,處理類中非常重要的一個(gè)方法headler()用來執(zhí)行服務(wù)端程序中的核心操作

class mytcpserver(socketserver.StreamRequestHandler):
    def handle(self):
        # 服務(wù)器中的核心操作代碼
  • socketserver中的結(jié)構(gòu)?
    socketserver中主要包含兩部分:服務(wù)器和處理類
    服務(wù)類就是socketserver提供了內(nèi)置服務(wù)類拍鲤,如TCPserver贴谎、UDPserver等等
    處理類就是我們自定義的處理類,處理類中會(huì)包含handle()方法用于業(yè)務(wù)處理

2. 服務(wù)端編程

2.1. TCP服務(wù)端編程

使用socketserver編寫服務(wù)端程序如下:

import socketserver


# 自定義處理類
class myTcp(socketserver.StreamRequestHandler):
    # 定義處理方法
    def handle(self):
        # 通過client_address屬性查看連接進(jìn)來的服務(wù)器
        print("連接上的服務(wù)器:%s" % str(self.client_address))
        while True:
            # 接收客戶端發(fā)送的數(shù)據(jù)
            msg = self.request.recv(1024)
            if not msg:
                break;
            print("客戶端發(fā)過來消息:%s" % msg.decode("UTF-8"))
            # 給客戶端返回接收信息
            self.request.sendall("已經(jīng)成功接收您發(fā)送的消息".encode("UTF-8"))


# 程序從主線程直接運(yùn)行
if __name__ == "__main__":
    # 創(chuàng)建服務(wù)端對(duì)象季稳,指定處理類擅这,并監(jiān)聽8888端口
    server = socketserver.TCPServer(('', 8888), myTcp)
    # 啟動(dòng)服務(wù)端程序
    server.serve_forever()

此時(shí),我們使用常規(guī)模式開發(fā)客戶端程序如下:

import socket

sc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sc.connect(("192.168.10.108", 8888))

while True:
    msg = input("請(qǐng)輸入要發(fā)送的內(nèi)容:")
    if not msg or msg == "exit":
        break
    sc.sendall(msg.encode("UTF-8"))
    msg = sc.recv(1024)
    print("服務(wù)器回應(yīng):" + msg.decode("UTF-8"))

sc.close()

運(yùn)行上述程序景鼠,就可以和之前一樣蕾哟,實(shí)現(xiàn)客戶端和服務(wù)端之間的數(shù)據(jù)通信了;
和以前不一樣的時(shí)莲蜘,此時(shí)我們?nèi)绻P(guān)閉了客戶端,服務(wù)端程序還是在運(yùn)行的帘营,如果重新啟動(dòng)客戶端票渠,客戶端又會(huì)接入服務(wù)端,重新建立連接并通信芬迄。

2.2. UDP服務(wù)端編程

使用socketserver的UDPServer服務(wù)類和DatagramRequestHandler處理類進(jìn)行服務(wù)端的編程處理如下:

import socketserver

# 創(chuàng)建自定義處理類
class myUdp(socketserver.DatagramRequestHandler):
    # 創(chuàng)建自定義處理方法
    def handle(self):
        # 打印連接進(jìn)來的客戶端信息
        print("連接到服務(wù)器的主機(jī):" + str(self.client_address))

        # 收發(fā)消息
        while True:
            # 接收客戶端發(fā)送的消息
            # msg = self.request.recv()
            msg = self.rfile.readline()
            if not msg:
                break
            print("接受到客戶端發(fā)送的消息:%s" % msg.decode("UTF-8"))
            # 發(fā)送消息
            self.wfile.write("接收到您發(fā)送的消息".encode("UTF-8"))
# 主模塊線程中運(yùn)行程序
if __name__ == "__main__":
    # 創(chuàng)建UDP服務(wù)器對(duì)象
    server = socketserver.UDPServer(("", 8989), myUdp)
    # 啟動(dòng)UDP服務(wù)器
    server.serve_forever()

使用常規(guī)的方式開發(fā)UDP客戶端代碼如下:

import socket

sc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

while True:
    data = input("請(qǐng)輸入要發(fā)送的消息:")
    if not data or data == "exit":
        break

    sc.sendto(data.encode("UTF-8"), ("192.168.10.108", 8989))

    data,recv = sc.recvfrom(1024)
    if not data:
        break
    print("服務(wù)器返回消息:" + data.decode("UTF-8"))

sc.close()

此時(shí)啟動(dòng)服務(wù)端程序问顷,啟動(dòng)客戶端程序,就可以實(shí)現(xiàn)服務(wù)端和客戶端時(shí)間的數(shù)據(jù)通信了。
另外:你可以試試啟動(dòng)多個(gè)客戶端程序看看杜窄,有彩蛋哦肠骆。

3. 服務(wù)端并發(fā)

關(guān)于使用多線程或者多進(jìn)程并發(fā)的方式也是比較簡(jiǎn)單的,參考代碼如下塞耕,如果有興趣的話蚀腿,等學(xué)習(xí)完并發(fā)編程之后,可以再回過頭看看ThreadingTCPServer和ForkingTCPServer這樣多線程和多進(jìn)程并發(fā)的操作哦
服務(wù)端參考代碼:

import socketserver

class myTcp(socketserver.StreamRequestHandler):
    def handle(self):
        while True:
            data = self.request.recv(1024)
            print("接收到數(shù)據(jù):" + data.decode("UTF-8"))
            self.request.sendall("數(shù)據(jù)已經(jīng)接收成功".encode("UTF-8"))

if __name__ == "__main__":
    server = socketserver.ThreadingTCPServer(("", 9000), myTcp)
    server.serve_forever()

客戶端還是常規(guī)的客戶端

import socket

sc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

sc.connect(("192.168.10.108", 9000))

while True:
    msg = input("請(qǐng)輸入要發(fā)送的內(nèi)容:")
    if not msg or msg == "exit":
        break
    sc.sendall(msg.encode("UTF-8"))
    msg = sc.recv(1024)
    print("服務(wù)器回應(yīng):" + msg.decode("UTF-8"))

sc.close()

大牧莫邪.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扫外,一起剝皮案震驚了整個(gè)濱河市莉钙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌筛谚,老刑警劉巖磁玉,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異驾讲,居然都是意外死亡蚊伞,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門吮铭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來时迫,“玉大人,你說我怎么就攤上這事沐兵”鹂澹” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵扎谎,是天一觀的道長(zhǎng)碳想。 經(jīng)常有香客問我,道長(zhǎng)毁靶,這世上最難降的妖魔是什么胧奔? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮预吆,結(jié)果婚禮上龙填,老公的妹妹穿的比我還像新娘。我一直安慰自己拐叉,他們只是感情好岩遗,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凤瘦,像睡著了一般宿礁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蔬芥,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天梆靖,我揣著相機(jī)與錄音控汉,去河邊找鬼。 笑死返吻,一個(gè)胖子當(dāng)著我的面吹牛姑子,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播测僵,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼街佑,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了恨课?” 一聲冷哼從身側(cè)響起舆乔,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎剂公,沒想到半個(gè)月后希俩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纲辽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年颜武,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拖吼。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鳞上,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吊档,到底是詐尸還是另有隱情篙议,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布怠硼,位于F島的核電站鬼贱,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏香璃。R本人自食惡果不足惜这难,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望葡秒。 院中可真熱鬧姻乓,春花似錦、人聲如沸眯牧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽学少。三九已至剪个,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間旱易,已是汗流浹背禁偎。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阀坏,地道東北人如暖。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像忌堂,于是被迫代替她去往敵國和親盒至。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理士修,服務(wù)發(fā)現(xiàn)枷遂,斷路器,智...
    卡卡羅2017閱讀 134,601評(píng)論 18 139
  • 從三月份找實(shí)習(xí)到現(xiàn)在棋嘲,面了一些公司酒唉,掛了不少,但最終還是拿到小米沸移、百度痪伦、阿里、京東雹锣、新浪网沾、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,194評(píng)論 11 349
  • 我愿意 與你一起 不分離 什么時(shí)候 我對(duì)你的愛 變成了 懷疑 贊美的歌 出口卻是 怨言 看不見了你面 我是孤兒
    金火丁閱讀 99評(píng)論 0 0
  • 有聊的來的朋友真好,他能理解你的笑點(diǎn)攒射,你能接受他的玩笑醋旦。
    我很酷所以我不吃青菜閱讀 255評(píng)論 0 0
  • 作者:沈淋 導(dǎo)師:劉艷 袁浩 鄭鵬 這是一幅自我介紹的思維導(dǎo)圖,第一個(gè)主干是我的家鄉(xiāng)成都匆篓,熊貓是成都的標(biāo)志浑度,一提到...
    梅女士51閱讀 446評(píng)論 1 1