您的位置:首页 > 理论基础 > 计算机网络

python模块介绍- SocketServer 网络服务框架

2013-05-22 21:06 711 查看

python模块介绍- SocketServer 网络服务框架

2013-05-22磁针石

#承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319 博客:http://blog.csdn.net/oychw

#版权所有,转载刊登请来函联系

# 深圳测试自动化python项目接单群113938272深圳会计软件测试兼职 6089740

#深圳地摊群 66250781武冈洞口城步新宁乡情群49494279

#自动化测试和python群组: http://groups.google.com/group/automation_testing_python
#参考资料:《The Python Standard Library by Example2011》

# http://docs.python.org/2/howto/sockets.html

11.3 SocketServer– 网络服务框架

SocketServer简化了网络服务器的编写。它有4个类:TCPServer,UDPServer,UnixStreamServer,UnixDatagramServer。这4个类是同步进行处理的,另外通过ForkingMixIn和ThreadingMixIn类来支持异步。

创建服务器的步骤。首先,你必须创建一个请求处理类,它是BaseRequestHandler的子类并重载其handle()方法。其次,你必须实例化一个服务器类,传入服务器的地址和请求处理程序类。最后,调用handle_request()或serve_forever()。

当继承自ThreadingMixIn为螺纹连接行为,你应该明确线程异常关闭时如何处理。ThreadingMixIn类的daemon_threads指示服务器是否应该等待线程终止,默认值为False。

无论用什么网络协议,服务器类有相同的外部方法和属性。

11.3.1 服务器类型

注意:BaseServer不直接对外服务。

+------------+

| BaseServer|

+------------+

|

v

+-----------+ +------------------+

|TCPServer |------->| UnixStreamServer |

+-----------+ +------------------+

|

v

+-----------+ +--------------------+

|UDPServer |------->| UnixDatagramServer |

+-----------+ +--------------------+

11.3.2 服务器对象(略)

11.3.3 实现服务器

通常情况下使用默认配置即可,一下方法可重载。

•verify_request(request, client_address): 返回True如果处理请求,反之返回False。忽略它。比如只处理指定ip区间的请求。

•process_request(request, client_address):调用finish_request()处理请求,也可以创建单独的现成或者进程。
•finish_request(request,client_address):创建一个请求处理实例,调用实例的handle()。

11.3.4 请求处理器

处理器接收数据并决定如何操作。它负责在socket层之上实现协议(i.e.,HTTP, XML-RPC, or AMQP).可以重载的方法如下:

• setup(): 准备请求处理. StreamRequestHandler中会创建文件类似的对象。forreading from and writing to the socket.

• handle(): 处理请求。解析传入的请求,处理数据,并发送响应。

• finish(): 环境清理。

通常只需要重载handle。

11.3.5 Echo实例

完整起见,这里列出了所有方法。后面有简化版本。另外,服务器和客服端放在一个脚本。

importlogging

import sys

importSocketServer

logging.basicConfig(level=logging.DEBUG,

format='%(name)s:%(message)s',

)

classEchoRequestHandler(SocketServer.BaseRequestHandler):

def __init__(self, request, client_address,server):

self.logger =logging.getLogger('EchoRequestHandler')

self.logger.debug('__init__')

SocketServer.BaseRequestHandler.__init__(self, request,

client_address,

server)

return

def setup(self):

self.logger.debug('setup')

returnSocketServer.BaseRequestHandler.setup(self)

def handle(self):

self.logger.debug('handle')

# Echo the back to the client

data = self.request.recv(1024)

self.logger.debug('recv()->"%s"', data)

self.request.send(data)

return

def finish(self):

self.logger.debug('finish')

returnSocketServer.BaseRequestHandler.finish(self)

classEchoServer(SocketServer.TCPServer):

def __init__(self, server_address,

handler_class=EchoRequestHandler,

):

self.logger = logging.getLogger('EchoServer')

self.logger.debug('__init__')

SocketServer.TCPServer.__init__(self,server_address,

handler_class)

return

def server_activate(self):

self.logger.debug('server_activate')

SocketServer.TCPServer.server_activate(self)

return

def serve_forever(self, poll_interval=0.5):

self.logger.debug('waiting forrequest')

self.logger.info('Handling requests,press <Ctrl-C> to quit')

SocketServer.TCPServer.serve_forever(self,poll_interval)

return

def handle_request(self):

self.logger.debug('handle_request')

returnSocketServer.TCPServer.handle_request(self)

def verify_request(self, request,client_address):

self.logger.debug('verify_request(%s,%s)',

request,client_address)

returnSocketServer.TCPServer.verify_request(self, request,

client_address)

def process_request(self, request,client_address):

self.logger.debug('process_request(%s,%s)',

request,client_address)

returnSocketServer.TCPServer.process_request(self, request,

client_address)

def server_close(self):

self.logger.debug('server_close')

returnSocketServer.TCPServer.server_close(self)

def finish_request(self, request, client_address):

self.logger.debug('finish_request(%s,%s)',

request,client_address)

returnSocketServer.TCPServer.finish_request(self, request,

client_address)

def close_request(self, request_address):

self.logger.debug('close_request(%s)',request_address)

returnSocketServer.TCPServer.close_request(self,

request_address)

def shutdown(self):

self.logger.debug('shutdown()')

returnSocketServer.TCPServer.shutdown(self)

if __name__== '__main__':

import socket

import threading

address = ('localhost', 0) # let the kernelassign a port

server = EchoServer(address,EchoRequestHandler)

ip, port = server.server_address # whatport was assigned?

# Start the server in a thread

t =threading.Thread(target=server.serve_forever)

t.setDaemon(True) # don't hang on exit

t.start()

logger = logging.getLogger('client')

logger.info('Server on %s:%s', ip, port)

# Connect to the server

logger.debug('creating socket')

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

logger.debug('connecting to server')

s.connect((ip, port))

# Send the data

message = 'Hello, world'

logger.debug('sending data:"%s"', message)

len_sent = s.send(message)

# Receive a response

logger.debug('waiting for response')

response = s.recv(len_sent)

logger.debug('response from server:"%s"', response)

# Clean up

server.shutdown()

logger.debug('closing socket')

s.close()

logger.debug('done')

server.socket.close()

执行结果:

]#./SocketServer_echo.py

EchoServer:__init__

EchoServer:server_activate

EchoServer:waiting for request

EchoServer:Handling requests, press <Ctrl-C> to quit

client:Server on 127.0.0.1:48354

client:creating socket

client:connecting to server

client:sending data: "Hello, world"

EchoServer:verify_request(<socket._socketobject object at 0x9f698b4>, ('127.0.0.1',38337))

EchoServer:process_request(<socket._socketobject object at 0x9f698b4>, ('127.0.0.1',38337))

client:waiting for response

EchoServer:finish_request(<socket._socketobject object at 0x9f698b4>, ('127.0.0.1',38337))

EchoRequestHandler:__init__

EchoRequestHandler:setup

EchoRequestHandler:handle

EchoRequestHandler:recv()->"Hello, world"

EchoRequestHandler:finish

client:response from server: "Hello, world"

EchoServer:shutdown()

EchoServer:close_request(<socket._socketobject object at 0x9f698b4>)

client:closing socket

client: done

简化版本:

importSocketServer

classEchoRequestHandler(SocketServer.BaseRequestHandler):

def handle(self):

# Echo the back to the client

data = self.request.recv(1024)

self.request.send(data)

return

if __name__== '__main__':

import socket

import threading

address = ('localhost', 0) # let the kernelassign a port

server = SocketServer.TCPServer(address,EchoRequestHandler)

ip, port = server.server_address # whatport was assigned?

t =threading.Thread(target=server.serve_forever)

t.setDaemon(True) # don't hang on exit

t.start()

# Connect to the server

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

s.connect((ip, port))

# Send the data

message = 'Hello, world'

print 'Sending : "%s"' % message

len_sent = s.send(message)

# Receive a response

response = s.recv(len_sent)

print 'Received: "%s"' % response

# Clean up

server.shutdown()

s.close()

server.socket.close()

执行结果:

#./SocketServer_echo_simple.py

Sending :"Hello, world"

Received:"Hello, world"

11.3.6 Threading 和 Forking

线程:

importthreading

importSocketServer

classThreadedEchoRequestHandler(SocketServer.BaseRequestHandler):

def handle(self):

# Echo the back to the client

data = self.request.recv(1024)

cur_thread = threading.currentThread()

response = '%s: %s' % (cur_thread.getName(),data)

self.request.send(response)

return

classThreadedEchoServer(SocketServer.ThreadingMixIn,

SocketServer.TCPServer,

):

pass

if __name__== '__main__':

import socket

import threading

address = ('localhost', 0) # let the kernelassign a port

server = ThreadedEchoServer(address,ThreadedEchoRequestHandler)

ip, port = server.server_address # whatport was assigned?

t = threading.Thread(target=server.serve_forever)

t.setDaemon(True) # don't hang on exit

t.start()

print 'Server loop running in thread:',t.getName()

# Connect to the server

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

s.connect((ip, port))

# Send the data

message = 'Hello, world'

print 'Sending : "%s"' % message

len_sent = s.send(message)

# Receive a response

response = s.recv(1024)

print 'Received: "%s"' % response

# Clean up

server.shutdown()

s.close()

server.socket.close()

执行结果:

# ./SocketServer_threaded.py

Server looprunning in thread: Thread-1

Sending :"Hello, world"

Received:"Thread-2: Hello, world"

进程:

import os

importSocketServer

classForkingEchoRequestHandler(SocketServer.BaseRequestHandler):

def handle(self):

# Echo the back to the client

data = self.request.recv(1024)

cur_pid = os.getpid()

response = '%s: %s' % (cur_pid, data)

self.request.send(response)

return

classForkingEchoServer(SocketServer.ForkingMixIn,

SocketServer.TCPServer,

):

pass

if __name__== '__main__':

import socket

import threading

address = ('localhost', 0) # let the kernelassign a port

server = ForkingEchoServer(address,ForkingEchoRequestHandler)

ip, port = server.server_address # whatport was assigned?

t =threading.Thread(target=server.serve_forever)

t.setDaemon(True) # don't hang on exit

t.start()

print 'Server loop running in process:',os.getpid()

# Connect to the server

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

s.connect((ip, port))

# Send the data

message = 'Hello, world'

print 'Sending : "%s"' % message

len_sent = s.send(message)

# Receive a response

response = s.recv(1024)

print 'Received: "%s"' % response

# Clean up

server.shutdown()

s.close()

server.socket.close()

执行结果:

# ./SocketServer_forking.py

Server loop running in process: 6288

Sending : "Hello, world"

Received: "6290: Hello, world"

参考资料:

SocketServer(http://docs.python.org/lib/module-SocketServer.html) Standard library documentationfor this module

asyncore (page 619) Use asyncore tocreate asynchronous servers that do not block

while processing a request.

SimpleXMLRPCServer (page 714) XML-RPCserver built using SocketServer.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: