105 socket-based programming of concurrency socketserver

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

  1. Examples of ftpserver obtained, first find the class ThreadingTCPServer the __init__, found in the TCPServer thereby carry server_bind, server_active
  2. Get serve_forever under ftpserver, BaseServer found, the execution further self._handle_request_noblock (), which is likewise in the BaseServer
  3. 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)
  4. 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)
  5. 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

  1. self.server socket object that is
  2. self.request that is a link
  3.   self.client_address namely client address

Udp-based class of socketserver our own definition of

  1.   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)>)
  2.   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"))

Guess you like

Origin www.cnblogs.com/XuChengNotes/p/11495851.html
Recommended