面向TCP协议的套接字服务端编程
实现网络服务器TCPServer类
功能、属性即函数一览:
实现代码:
# -*- encoding=utf-8 -*-
import socket
import threading
class TCPServer:
def __init__(self, server_address, handler_class):
self.server_address = server_address
self.HandlerClass = handler_class
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.is_shutdown = False
# 服务器的启动函数
def serve_forever(self):
self.socket.bind(self.server_address)
self.socket.listen(10)
# while True:
while not self.is_shutdown:
# 1. 接收请求
request, client_address = self.get_request()
# 2. 处理请求
try:
# self.process_request(request, client_address)
self.process_request_multithread(request, client_address)
except Exception as e:
print(e)
pass
# 接收请求
def get_request(self):
return self.socket.accept()
# 处理请求
def process_request(self, request, client_address):
handler = self.HandlerClass(self, request, client_address)
handler.handle()
# 3. 关闭连接
self.close_request(request)
# 多线程处理请求
def process_request_multithread(self, request, client_address):
t = threading.Thread(target=self.process_request,
args=(request, client_address))
t.start()
# 关闭请求
def close_request(self, request):
request.shutdown(socket.SHUT_WR)
request.close()
# 关闭服务器
def shutdown(self):
self.is_shutdown = True
pass
实现网络请求处理器Handler类
实现代码:
# -*- encoding=utf-8 -*-
class BaseRequestHandler:
def __init__(self, server, request, client_address):
self.server = server
self.request = request
self.client_address = client_address
def handle(self):
pass
class StreamRequestHandler(BaseRequestHandler):
def __init__(self, server, request, client_address):
BaseRequestHandler.__init__(self, server, request, client_address)
self.rfile = self.request.makefile('rb')
self.wfile = self.request.makefile('wb')
self.wbuf = []
# 编码:字符串->字节码
def encode(self, msg):
if not isinstance(msg, bytes):
msg = bytes(msg, encoding='utf-8')
return msg
# 解码:字节码->字符串
def decode(self, msg):
if isinstance(msg, bytes):
msg = msg.decode()
return msg
# 读消息
def read(self, length):
msg = self.rfile.read(length)
return self.decode(msg)
# 读取一行消息
def readline(self, length=65536):
msg = self.rfile.readline(length).strip()
return self.decode(msg)
# 写消息
def write_content(self, msg):
msg = self.encode(msg)
self.wbuf.append(msg)
# 发送消息
def send(self):
for line in self.wbuf:
self.wfile.write(line)
self.wfile.flush()
self.wbuf = []
def close(self):
self.wfile.close()
self.rfile.close()
编写网络服务器测试用例
# -*- encoding=utf-8 -*-
import time
import socket
import threading
from server.socket_server import TCPServer
from handler.base_handler import StreamRequestHandler
from server.base_http_server import BaseHTTPServer
from handler.base_http_handler import BaseHTTPRequestHandler
class TestBaseRequestHandler(StreamRequestHandler):
# 具体处理的逻辑(Echo)
def handle(self):
msg = self.readline()
print('Server recv msg: ' + msg)
time.sleep(1)
self.write_content(msg)
self.send()
pass
# 测试SocketServer(TCPServer)
class SocketServerTest:
def run_server(self):
tcp_server = TCPServer(('127.0.0.1', 8888), TestBaseRequestHandler)
tcp_server.serve_forever()
# 客户端的具体连接逻辑
def client_connect(self):
client = socket.socket()
client.connect(('127.0.0.1', 8888))
client.send(b'Hello TCPServer\r\n')
msg = client.recv(1024)
print('Client recv msg: ' + msg.decode())
# 生成客户端
def gen_clients(self, num):
clients = []
for i in range(num):
client_thread = threading.Thread(target=self.client_connect)
clients.append(client_thread)
return clients
def run(self):
server_thread = threading.Thread(target=self.run_server)
server_thread.start()
clients = self.gen_clients(10)
for client in clients:
client.start()
server_thread.join()
for client in clients:
client.join()
class BaseHTTPRequestHandlerTest:
def run_server(self):
BaseHTTPServer(('127.0.0.1', 9999), BaseHTTPRequestHandler).serve_forever()
def run(self):
self.run_server()
if __name__ == '__main__':
# SocketServerTest().run()
BaseHTTPRequestHandlerTest().run()
运行结果: