欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于python socketserver框架全面解析

 更新時(shí)間:2017年09月21日 08:24:19   作者:又見阿郎  
下面小編就為大家?guī)?lái)一篇基于python socketserver框架全面解析。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧

socketserver框架是一個(gè)基本的socket服務(wù)器端框架, 使用了threading來(lái)處理多個(gè)客戶端的連接, 使用seletor模塊來(lái)處理高并發(fā)訪問, 是值得一看的python 標(biāo)準(zhǔn)庫(kù)的源碼之一

對(duì)于select網(wǎng)絡(luò)框架的理解可以看 << 基于python select.select模塊通信的實(shí)例講解 >>。socketserver框架采用了selector框架來(lái)供你選擇相適應(yīng)的網(wǎng)絡(luò)通信框架, 比如select, poll, epoll等。有了這些網(wǎng)絡(luò)框架我們就能處理高并發(fā)的網(wǎng)絡(luò)訪問了.

先看看示例代碼吧:

# coding: utf-8
import socketserver


class MyTCPHandler(socketserver.BaseRequestHandler):
 """
 The request handler class for our server.
 It is instantiated once per connection to the server, and must
 override the handle() method to implement communication to the
 client.
 """

 def handle(self):
  # self.request is the TCP socket connected to the client
  self.data = self.request.recv(1024).strip()
  print("{} wrote:".format(self.client_address[0]))
  print(self.data)
  # just send back the same data, but upper-cased
  self.request.sendall(self.data.upper())


if __name__ == "__main__":
 HOST, PORT = "localhost", 9999

 # Create the server, binding to localhost on port 9999
 # 如果子類沒有某個(gè)方法或是屬性, 就回去父類中調(diào)用
 with socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler) as server:
  # Activate the server; this will keep running until you
  # interrupt the program with Ctrl-C
  server.serve_forever()

客戶端:

# coding: utf-8
import socket


sk = socket.socket()
sk.connect(("127.0.0.1", 9999)) # 主動(dòng)初始化與服務(wù)器端的連接
while True:
 send_data = input("輸入發(fā)送內(nèi)容:")
 sk.sendall(bytes(send_data, encoding="utf8"))
 if send_data == "byebye":
  break
 accept_data = str(sk.recv(1024), encoding="utf8")
 print("".join(("接收內(nèi)容:", accept_data)))
sk.close()

我們創(chuàng)建一個(gè)繼承自BaseRequestHandler類的TCP請(qǐng)求處理類, 說白了這個(gè)類就是我們自己封裝的基于socket的recv()函數(shù)與send()函數(shù)的類, 而所謂的TCP請(qǐng)求處理類其實(shí)就是對(duì)socket服務(wù)器端的bind, listen, accept等處理的封裝類, 而且這個(gè)封裝的并不是簡(jiǎn)單的socket, 而是基于select或是epoll等網(wǎng)絡(luò)框架的類, 我們調(diào)用這個(gè)類就能輕易地處理高并發(fā)的網(wǎng)絡(luò)訪問. 其實(shí)認(rèn)真閱讀源碼, 你會(huì)發(fā)現(xiàn)整體的程序設(shè)計(jì)是基于事件驅(qū)動(dòng)的, 事件驅(qū)動(dòng)機(jī)制的三個(gè)要素: 消息(事件)隊(duì)列, 消息(事件)觸發(fā), 事件循環(huán)。只不過socketserver框架的事件驅(qū)動(dòng)機(jī)制就做到了socket的accept()方法那, 接下來(lái)的消息接受(recv)與發(fā)送(send)就沒有在做封裝成相應(yīng)的事件來(lái)進(jìn)行處理了。

在這里說一個(gè)要注意的地方, 我使用了ThreadingTCPServer()類響應(yīng)多個(gè)客戶端的連接, 但是當(dāng)我閱讀這個(gè)類的源碼的時(shí)候, 表示很疑惑?。?/p>

class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass

這讓我很疑惑啊,再看看調(diào)用:

with socketserver.ThreadingTCPServer((HOST, PORT), MyTCPHandler) as server:
  # Activate the server; this will keep running until you
  # interrupt the program with Ctrl-C
  server.serve_forever()

這更疑惑, ThreadingTCPServer哪來(lái)的構(gòu)造函數(shù), 后來(lái)研究了一下, 原來(lái)當(dāng)子類的某個(gè)函數(shù)或是屬性發(fā)生調(diào)用時(shí), 如果不是重載了父類的方法或是屬性, 而且子類中沒有這個(gè)方法或是屬性, 就會(huì)去調(diào)用父類相對(duì)應(yīng)的方法或是屬性, 于是上面的就是調(diào)用了TCPServer的初始化函數(shù)__init__以及serve_forever(), 隨后調(diào)用的是子類的Request_handler函數(shù)

程序結(jié)果:

以上這篇基于python socketserver框架全面解析就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論