python中的sockeserver模塊簡單實用


1、 socketserver模塊簡介


在python的socket編程中,實用socket模塊的時候,是不能實現多個連接的,當然如果加入其它的模塊是可以的,例如select模塊,在這里見到的介紹下socketserver模塊。


socketserver,看其名字,就知道是一個socket的服務器模塊的使用,在這個模塊中,主要也就是實現服務器類的相關功能,在其中,也就是將socket模塊和select模塊進行了封裝,從而創建了一些基類供人使用。


2、 socketserver服務器端和客戶端代碼

在socketserver模塊中,主要就是使用一些服務器類,從而簡化socket網絡編程的方法,先上一段基本的服務器代碼:

#!/usr/bin/env python

import SocketServer
import time


HOST = '192.168.1.60'
PORT = 9999

class MyHandler(SocketServer.BaseRequestHandler):
    def handle(self):
        while True:
            data = self.request.recv(1024)
            print data,self.client_address
            self.request.send( ' %s %s ' % (data,time.ctime()))
            if data == 'exit':
                break

s = SocketServer.ThreadingTCPServer((HOST,PORT),MyHandler)
s.serve_forever()

在上述的代碼中,僅僅做了幾件事,先定義了一個類,也就是處理請求的類,從基類baserequesthandler繼承,主要就是重寫其中handle方法,告知服務器如何來處理客戶端的請求。

然后創建了一個線程的TCP服務器類,也就是通過多線程來進行應答客戶端,然后使用一直運行的方法也就是serve_forever。


客戶端代碼如下:

#!/usr/bin/env python

import socket

HOST = '192.168.1.60'
PORT = 9999

s = socket.socket()
s.connect((HOST,PORT))
while True:
    kel = raw_input('>>>')
    s.sendall(kel)
    print s.recv(1024)
    if kel == 'exit':
        break
s.close()
客戶端的代碼和socket編程的代碼基本相同,因為在socketserver模塊中,主要是創建socke的服務端,而不涉及到客戶端,從而客戶端不需要修改代碼即可進行運行。


對比此段代碼和socket編程的區別是:可以和多個client端同時進行通信。

[root@python 514]# ps -ef|grep python
root      8628  6091  0 12:56 pts/3    00:00:00 python server.py
root      8629 32625  0 12:56 pts/0    00:00:00 python client.py
root      8656  8634  0 12:56 pts/1    00:00:00 python client.py

在單純的socket編碼中,同時只能一個進行通信,其他的連接會被阻塞。


3、 socketserver模塊類介紹

在socketserver的默認請求處理器中,是接收連接,得到請求,然后就關閉連接,從而也就是客戶端在循環的時候,必須每次都進行重新連接。

在上面的代碼中,重寫了事件處理的方法handle,在其中使用了循環,也就是一直保持和客戶端的連接。


請求處理的基類是BaseRequestHandler,其中一般需要重寫的方法就是handle方法,主要就是如何處理接下來的請求,在這個類里,主要有三個方法,一個是setup,handle和finish方法,在調用這個類的時候,先調用setup進行一些初始化的工作,然后調用handle方法進行處理請求,然后調用finish方法,做一些關閉連接什么的;在這個里面最主要的參數self.request,也就是請求的socket對象,其中可以發送消息sendall或者send,接收消息的recv

在請求處理的子類中有兩個,一個是SreamRequestHandle和DatagramRequestHandle,在這個里面重寫了基類的setup方法和finish方法,handle方法沒有重寫,因為這個是留給用戶做處理請求的方法,在這里提供了幾個參數,一個self.rfile用來讀取數據的句柄,而self.wfile是用來發送消息的句柄。

在使用rfile和wfile時候需要注意,在客戶端發送消息的時候需要自己加上回車,而在服務器端需要使用readline方法來進行讀取,也就是讀取一行,如下所示服務器端代碼:

#!/usr/bin/env python

import SocketServer
import time


HOST = '192.168.1.60'
PORT = 9999

class MyHandler(SocketServer.StreamRequestHandler):
    def handle(self):
        while True:
            data = self.rfile.readline().strip()
            print data,self.client_address
            self.wfile.write( ' %s %s ' % (data,time.ctime()))
            if data == 'exit':
                break

s = SocketServer.ThreadingTCPServer((HOST,PORT),MyHandler)
s.serve_forever()
在使用rfile的時候,需要使用readline方法,否則會卡住請求的處理,而在客戶端代碼如下:

#!/usr/bin/env python

import socket

HOST = '192.168.1.60'
PORT = 9999

s = socket.socket()
s.connect((HOST,PORT))
while True:
#    s = socket.socket()
#    s.connect((HOST,PORT))
    kel = raw_input('>>>')
    s.sendall(kel + '\n')
    print s.recv(1024)
    if kel == 'exit':
        break
s.close()
在進行sendall數據的時候,需要加上''\n',表示此次發送的數據結束。


最基類的是服務器類BaseServer類,其中定義了相關的方法,不能直接使用這個類,只能用來繼承,在子類中有倆,是作為同步服務器類使用,TCPServer和UDPServer,這兩個類主要是和socket編程的時候是相同的,也就是會阻塞連接。TCPServer有一個子類為UNIXStreamServer,在UDPServer有一個子類為UnixDatagramServer,在最后的兩個子類中,是基於文件同步的tcp和udp服務器。


兩個混合類,一個是ForkingMixin,主要是用fork的,產生一個新的進程去處理;一個是ThreadingMixin,產生一個新的線程,主要是用來提供異步處理的能力,其余tcpserver和udpserver組合,又產生了新的四個類,從而提供異步處理的能力。


在使用混合類和服務器類的時候,注意混合類需要寫在前面,因為混合類重寫了服務器類的方法,從而需要放在第一個位置。


總結:

python中的socketserver模塊,主要是用來提供服務器類,並且提供異步處理的能力。








免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM