Python网络编程之socketserver的使用

在Python2.x中需要import SocketServer,在Python3.x中,都变成了小写,需要import sockerserver

Python Version: 3.5+

  • server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import socketserver

# 自定义socketserver需要继承socketserver.BaseRequestHandler
class MyServer(socketserver.BaseRequestHandler):

# 每一个对象实例化的时候,都会执行handle里面的代码
# 自定义的handle方法会重写父类的handle方法,主要用来与客户端进行交互
def handle(self):
conn = self.request
# 这条欢迎消息会在每个客户端连上之后发送
conn.sendall(bytes("Welcome to docs.20150509.cn", encoding='utf8'))
while True:
recv_data = conn.recv(1024)
if len(recv_data) == 0:break
conn.sendall(recv_data.upper())

if __name__ == "__main__":
server = socketserver.ThreadingTCPServer(('127.0.0.1', 5959), MyServer)
# 每多一个客户端的连接,就睡多起一个线程去处理
server.serve_forever()
  • client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import socket

ip_port = ('127.0.0.1', 5959)
s = socket.socket()
s.connect(ip_port)

# 首先接收服务端发来的欢迎消息
welcome_msg = s.recv(1024)
print(str(welcome_msg, encoding='utf-8'))

while True:
# 输入消息
sent_data = input("> ").strip()
if len(sent_data) == 0: continue
# 发送消息
s.send(bytes(sent_data, encoding='utf8'))

# 接收消息
recv_data = s.recv(1024)
print(str(recv_data, encoding='utf-8'))

s.close()
  • 执行
1
2
3
4
Welcome to docs.20150509.cn
> polarsnow
POLARSNOW
>

多个客户端可以同时连接使用,每个客户端连接时都会创建一个对象,在服务端都会新起一个进来来负责这个线程的处理

浅谈源码

我们就来看看继承的socketserver.BaseRequestHandler的源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class BaseRequestHandler:

"""Base class for request handler classes.

This class is instantiated for each request to be handled. The
constructor sets the instance variables request, client_address
and server, and then calls the handle() method. To implement a
specific service, all you need to do is to derive a class which
defines a handle() method.

The handle() method can find the request as self.request, the
client address as self.client_address, and the server (in case it
needs access to per-server information) as self.server. Since a
separate instance is created for each request, the handle() method
can define arbitrary other instance variariables.

"""

def __init__(self, request, client_address, server):
self.request = request
self.client_address = client_address
self.server = server
self.setup()
try:
self.handle()
finally:
self.finish()

def setup(self):
pass

def handle(self):
pass

def finish(self):
pass

我没有省略,源码中只有这几行

可以看出,创建对象执行构造方法的时候,会自动去执行三个方法

  • self.setup() 负责客户端连接时的处理
  • self.handle() 负责客户端连接后的交互
  • self.finish() 负责客户端断开前的操作

在我们自己的类中,可以通过重写父类的这方法来实现对客户端请求的处理