16.4节SocketServer模块
本节书中只是大略介绍了这个模块的一些类,但是并不具体,如果要深入研究,可能还得看相关参考资料。
关于本节的两个例子,其实思路都是一样的。但是还是有一些区别,看代码中的注释吧。
#-*-coding: utf-8-*-
"""使用SocketServer里的TCPServer和StreamRequestHandler类创建一个时间戳TCP服务器。
"""
from SocketServer import (TCPServer as TCP,
StreamRequestHandler as SRH) # 使用多行导入
from time import ctime
HOST = ''
PORT = 21567
ADDR = (HOST, PORT)
class MyRequestHandler(SRH): # 从StreamRequestHandler(SRH)类中派生出一个子类,并重写handle()函数,因为在BaseServer中,handle()函数的内容是pass
def handle(self):
print "...connected from:", self.client_address # 父类SRH
self.wfile.write('[%s] %s' % (ctime(), self.rfile.readline())) # StreamRequestHandler类的套接字能读写?readline()获取客户端信息,write()将信息发送给客户端
tcpServ = TCP(ADDR, MyRequestHandler) # 给定主机地址和请求处理类,创建TCP服务器(实例化)。绑定主机在此步骤完成?
print "waiting for connection..."
tcpServ.serve_forever() # 进入服务器无限循环,serve_forever()也能跟之前一样创建临时套接字,再进行通信循环?
#-*-coding: utf-8-*-
from socket import *
HOST = 'localhost'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)
while True:
tcpCliSock = socket(AF_INET, SOCK_STREAM) # SocketServer的请求处理器默认是得到一个请求后就断开连接,所以不能像之前那样一直保持连接,因此每次发送信息给服务器都得新建一个套接字。
tcpCliSock.connect(ADDR)
data = raw_input('> ')
if not data:
break
tcpCliSock.send('%s\r\n' % data)
data = tcpCliSock.recv(BUFSIZ)
if not data:
break
print data.strip() # 服务器保留了后面的'\r\n',所以需用strip()函数将其去掉
tcpCliSock.close()