爲了快速搭建服務器,標準庫中有個高級模塊SocketServer
它提供了一些可供使用的類(使用類就是會了封裝那些繁瑣的細節)
我們來看看SocketServer中提供的2個重要的類
- TCPServer/UDPServer 網絡同步服務器
- StreamRequestHandler/DatagramRequestHandler 2種處理器,處理客戶請求
注:SocketServer請求處理器的默認行爲是:接收連接,得到請求,之後斷開連接。也就是說如果一個客戶想說好幾句話時,必須得說一句,建立一個Socket
本章還提到了“事件驅動”
事件驅動:只有在事件出現的時候,程序才做出反應
什麼是事件? 你點擊一個按鈕,就是觸發一個事件,電腦會對此做出反應。發生什麼事件就調用相應的函數進行處理,這就是事件驅動。我們可以定義事件類,並在這些類中定義處理器。這樣就可以快速的知道是什麼事件,進而快速調用相應處理器解決。這也是面向對象的編程思想。
非事件驅動:個人理解是發生一個事件後,程序首先會執行一系列操作來確定這是什麼事件,確定下來後纔會採用對應的方法進行解決。
下面的實例會實現一個請求處理器,只有當客戶提出請求時,就會調用該處理器來處理請求。沒有客戶接入時,CPU會暫時休息,這樣就對CPU進行有效利用。
創建TCP同步服務器
#-*- coding:utf-8 -*-
#導入一個TCP服務器類和一個流處理器(處理TCP請求)
from SocketServer import (TCPServer as TCP, \
StreamRequestHandler as SRH)
from time import ctime
HOST = 'localhost'
PORT = 20000
ADDR = (HOST, PORT)
class RequestHandler(SRH):
def handle(self):
print "...connected from", self.client_address
#處理器類可以像處理文件一樣處理Socket數據
self.wfile.write("[%s]%s"% (ctime(),self.rfile.readline()))
tcpServer = TCP(ADDR, RequestHandler) #創建一個TCP同步服務器
print "---waiting for connection----"
tcpServer.serve_forever() #開啓工作狂模式
創建TCP客戶端
#-*- coding:utf-8 -*-
from socket import *
HOST = "localhost"
PORT = 20000
ADDR = (HOST, PORT)
BUFSIZ = 1024
while True:
#因爲服務器處理器默認行爲是接收連接,得到請求,斷開連接。因此要想多次發送會話,就必須重新建立socket
tcpCliSock = socket(AF_INET, SOCK_STREAM)
tcpCliSock.connect(ADDR)
data = raw_input('>>>')
if not data:
break
#處理器類像文件一樣處理Socket數據,因此行結束要自己添加\r\n
tcpCliSock.send("%s\r\n" % data)
data = tcpCliSock.recv(BUFSIZ)
if not data:
break
print data.strip() #去掉行結束符\r\n
tcpCliSock.close() #掛電話