table of Contents
A, socketserver module
Based on tcp socket, the key is two cycles, a cycle link, a communication cycle
socketserver module carved into two categories: server class (link to solve the problem) and request class (to solve the communication problems)
Server class:
request categories:
Inheritance:
In the following code as an example, source code analysis socketserver:
ftpserver=socketserver.ThreadingTCPServer(('127.0.0.1',8080),FtpServer)
ftpserver.serve_forever()
Find the Order of Attributes : ThreadingTCPServer-> ThreadingMixIn-> TCPServer-> BaseServer
- Examples of ftpserver obtained, first find the class ThreadingTCPServer the __init__, found in the TCPServer thereby carry server_bind, server_active
- Get serve_forever under ftpserver, BaseServer found, the execution further self._handle_request_noblock (), which is likewise in the BaseServer
- Performing self._handle_request_noblock () performs addition request, client_address = self.get_request ((TCPServer is in self.socket.accept ())), then perform self.process_request (request, client_address)
- Found in ThreadingMixIn process_request, open multiple threads to deal with concurrency, and then execute process_request_thread, execution self.finish_request (request, client_address)
- The four partially completed cycle links, this part of the communication processing section began to enter, find finish_request in BaseServer, the trigger instantiate our own definition of class, go __init__ method, and our own definition of the class does not have this method, to its parent class is in BaseRequestHandler find ....
1.1 source code analysis summary:
Tcp-based class of socketserver our own definition of
- self.server socket object that is
- self.request that is a link
- self.client_address namely client address
Udp-based class of socketserver our own definition of
- self.request is a tuple (a first element is the data sent by the client, the server is a second portion of udp socket object), such as (b'adsf ', <socket.socket fd = 200, family = AddressFamily.AF_INET, type = SocketKind.SOCK_DGRAM, proto = 0, laddr = ( '127.0.0.1', 8080)>)
- self.client_address namely client address
Second, based on the TCP protocol
Server
'''
-tcp的服务端
-server=ThreadingTCPServer 创建对象
-server.serve_forever 开线程进行连接循环
-写一个类(继承BaseRequestHandler类),类里重写handle,方法内收发数据(并发起来了)
'''
#使用socketserver写服务端
import socketserver
HOST = "127.0.0.1"
PORT = 8080
#自己定义一个类,必须继承BaseRequestHandler
class MyTcp(socketserver.BaseRequestHandler):
# 必须重写handle方法
def handle(self):
try:
while 1:
# conn对象就是request
# 接收数据
print(self.client_address) # 客户机地址
data = self.request.recv(1024)
print(data.decode("utf8"))
if len(data) == 0:
return
# 发送数据
self.request.send(data.upper())
except:
print("出错了")
if __name__ == '__main__':
# 实例化得到一个tcp连接的对象
server = socketserver.ThreadingTCPServer((HOST,PORT),MyTcp)
# 这里开的线程,获取连接
server.serve_forever()
Client
import socket
soc=socket.socket()
soc.connect(('127.0.0.1',8080))
while True:
soc.send('你好'.encode('utf-8'))
print(soc.recv(1024).decode("utf8"))
Second, based on the UDP protocol
Server
import socketserver
HOST = "127.0.0.1"
PORT = 8081
class MyUDP(socketserver.BaseRequestHandler):
def handle(self):
print(self) # UDP连接对象
# 数据
print(self.request[0]) # 数据
print(self.request[1]) #
print(type(self.request[1]))
if __name__ == '__main__':
# 实例化得到一个tcp连接的对象,Threading意思是说,只要来了请求,它自动的开线程来处理连接跟交互数据
server = socketserver.ThreadingUDPServer((HOST,PORT),MyUDP)
# 一直在等待发送数据来
server.serve_forever()
Client
import socket
HOST = "127.0.0.1"
PORT = 8081
if __name__ == '__main__':
# 创建对象
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while 1:
# 发数据
client.sendto("123123".encode("utf8"),(HOST,PORT))
# 接收数据
print(client.recvfrom(1024)[0].decode("utf8"))