Explanation of Python Socket Programming

  • 2021-11-02 01:26:30
  • OfStack

Directory background
What are the essential differences between TCP and UDP protocols?
What are the differences and connections between TCP/IP protocol stack, HTTP protocol and Socket?
TCP Socket server communication process?
What is the connection between socket and websocket?
What are the connections and differences between HTTP and WSGI protocols?
Mainstream Web framework, asynchronous Web framework?
What is the connection between asyncio and aiohttp? (Asynchronous Programming)
Code design
TCP Socket Server
TCP Socket Client
UDP Socket
Summarize

Background

About Python Socket programming, we need to know several computer networks first. Through the following questions, we can better understand the significance of Socket programming and the knowledge of the whole framework:

What are the essential differences between TCP and UDP protocols?

TCP protocol, connection-oriented, reliable, based on byte stream transport layer communication protocol; UDP is a connectionless, unreliable, packet-based transport layer protocol.

TCP protocol needs to go through three handshakes in the process of establishing connection and four waves in the process of disconnecting connection, which increases the security in the transmission process.
The process of establishing connection will consume system resources and more time, while compared with UDP protocol transmission process, this problem will not occur.

To sum up, based on TCP protocol transmission, it is necessary to constantly confirm whether the other party receives information, so as to establish a connection (the number of confirmation processes is limited, that is, three handshakes), while UDP protocol transmission is
There is no need to confirm whether the receiver receives the message, just send the message to the other party.

What are the differences and connections between TCP/IP protocol stack, HTTP protocol and Socket?

TCP/IP protocol stack is a series of network protocols, which can be divided into four layers to analyze: application layer, transport layer, network layer and link layer;

HTTP protocol (Hypertext Transfer Protocol) is the application layer protocol in this 1 protocol stack; HTTP protocol simply, its role is to standardize the data format, so that the program can easily identify, and both the sending and receiving parties need to follow the same protocol format for data transmission. The application layer protocol is similar to the HTTP protocol, except that different data formats are defined. )

Socket can be understood as the external operation interface provided by TCP/IP protocol stack, that is, the interface for application layer to communicate through network protocol. Socket can use different network protocols for end-to-end communication;

TCP Socket server communication process?

Server End:

Establish a connection (socket () function creates an socket descriptor, bind () function binds a specific listening address (ip + port), listen () function listens for socket, and accept () blocks and waits for client connection)

Data interaction (read () function blocks waiting for client to send data, write () function sends data to client)

Client End:

Establishing a connection (socket () function creates an socket descriptor, and connect () function sends a connection request to the specified listening address)

Data interaction (wirte () function sends server data, read () function blocks waiting to receive data sent by server)

What is the connection between socket and websocket?

webosocket is a communication protocol, different from HTTP request, client request server resources, server response communication process; websocket allows the server to take the initiative
A protocol that pushes messages to the client and achieves two-way communication between the client and the server. (The specific underlying principle needs to be practiced later and has not been contacted for the time being)

What are the connections and differences between HTTP and WSGI protocols?

HTTP protocol (Hypertext Transfer Protocol) belongs to the TCP/IP protocol stack application layer protocol. Used to standardize the format of data transmission, it is a rule of client and server transmission.

WSGI protocol is the interface rule between Web server and framework program defined by Python. There is little connection between them. If you say it forcibly, Python framework program mainly handles HTTP requests.

(In the later stage, we can realize an Python framework of WSGI protocol, which is used to deal with the experiment of HTTP request.)

Mainstream Web framework, asynchronous Web framework?

Mainstream Web Framework: Django, Flask

Asynchronous Web framework: Tornado (built-in asynchronous module), Snaic (Python comes with asyncio), FastAPI (based on Starlette library), aiohttp (based on asyncio)

What is the connection between asyncio and aiohttp? (Asynchronous Programming)

asyncio is an asynchronous IO library, and aiohttp is an asynchronous HTTP framework based on asyncio (client/server support)

Code design

The Python provides the basic socket module:

socket module; Standard BSD Sockets API; socketserver module: Provides server center class to simplify server development;

TCP Socket Server

socket Module:


# -*- coding: utf-8 -*-
from socket import socket, AF_INET, SOCK_STREAM

def echo_handler(sock ,address):
	print("Get Connection from address:", address)

	while True:
		response = sock.recv(8192)
		if not response:
			break
		print(f"Got {response}")
		sock.sendall(response)

def echo_server(address, back_log=5):
	sock = socket(AF_INET, SOCK_STREAM)
	sock.bind(address)
	sock.listen(back_log)

	while True:
		sock_client, address = sock.accept()
		echo_handler(sock_client, address)

if __name__ == "__main__":
	echo_server(('localhost', 5000))

Detailed code explanation:

Create an Socket based on IPV4 and TCP protocols, where AF_INET refers to using IPV4 protocol, and SOCK_STREAM specifies using stream-oriented TCP protocol, binding listening ports, and setting the maximum number of waiting connections Create a permanent loop to get the connection requested by the client, and accept () will wait and return the connection of one client; After the connection is established, wait for the client data, accept the client data, then return the data to the client, and finally close the connection

Existing problems: When there are multiple client requests, because a single thread will block, so if you need to process multiple client requests with multiple threads, you can change it like this;


from threading import Thread

while True:
        client_sock, address = sock.accept()
        thread = Thread(target=echo_handler, args=(client_sock, address))
        thread.start()

In this way, when each client requests, a subthread will be generated and then the request will be processed;
(But there is a problem: When a large number of requests are made suddenly and the consumption of system resources reaches the upper limit, it is likely that the program will not be able to process subsequent requests.)

socketserver Module:


from socketserver import BaseRequestHandler, TCPServer

class EchoHandler(BaseRequestHandler):
    def handle(self):
        print("Got Connection From: %s" % str(self.client_address))
        while True:
            msg = self.request.recv(8192)
            if not msg:
                break
            self.request.send(msg)

if __name__ == "__main__":
    server = TCPServer(("", 5000), EchoHandler)
    server.serve_forever()

from socketserver import StreamRequestHandler, TCPServer, ThreadingTCPServer
import time

class EchoHandler(StreamRequestHandler):
    def handle(self):
        print("Got Connection Address: %s" % str(self.client_address))
        for line in self.rfile:
            print(line)
            self.wfile.write(bytes("hello {}".format(line.decode('utf-8')).encode('utf-8')))

if __name__ == "__main__":
    serv = ThreadingTCPServer(("", 5000), EchoHandler)
    serv.serve_forever()

Detailed code explanation:

Handle multiple clients and initialize one ThreadingTCPServer instance; Set the bound IP address and port, and handle the class; Using StreamRequestHandler (using stream request handler class, similar to file-like object, providing standard file interface to simplify the communication process), rewrite the handle method inside, obtain the request data, and return the data to the client;

TCP Socket Client

socket Module:


# -*- coding: utf-8 -*-
from socket import socket, AF_INET, SOCK_STREAM
import time

def request_handler():
	start_time = time.time()
	sock_client = socket(AF_INET, SOCK_STREAM)
	sock_client.connect(('localhost', 5000))
	
	book_content = ""
	with open("send_books.txt", "r") as f:
		book_content = f.read()
	
	content_list = book_content.split("\n")
	for content in content_list:
		if content:
			sock_client.send((content).encode())
			time.sleep(2)
			response = sock_client.recv(8192)
			print(response)

	end_time = time.time()
	print(" Total time spent :", end_time-start_time)

		

if __name__ == "__main__":
	request_handler()

UDP Socket

Socket Module:


from socket import socket, AF_INET, SOCK_DGRAM
import time

def time_server(address):
    sock = socket(AF_INET, SOCK_DGRAM)
    sock.bind(address)

    while True:
        msg, addr = sock.recvfrom(8192)
        print('Get message from', addr)
        resp = time.ctime()
        sock.sendto(resp.encode('ascii'), addr)

if __name__ == "__main__":
    time_server(('', 5000))

The code is unknown, similar to the previous one, pay attention to different protocols and it will be finished

Client testing:


from socket import socket, AF_INET, SOCK_DGRAM

if __name__ == "__main__":
    s = socket(AF_INET, SOCK_DGRAM)
    s.sendto(b'hello', ('localhost', 5000))
    text = s.recvfrom(8192)
    print(text)

socketserver Module:


from socketserver import BaseRequestHandler, UDPServer
import time


class TimeHandler(BaseRequestHandler):
    def handle(self):
        print("Got Connection %s".format(str(self.client_address)))
        data = self.request[0]
        print(data)
        msg, sock = self.request
        print(msg)
        data = time.ctime()
        sock.sendto(data.encode('ascii'), self.client_address)

if __name__ == "__main__":
    u = UDPServer(("localhost", 9999), TimeHandler)
    u.serve_forever()

The code is not repeated in detail. If you need to multithread concurrent operations, you can use ThreadingUDPServer

Summarize

About the introduction of Python Socket programming, most of them are superficial, but only talk about Python actual processing socket several modules,
About the socket underlying knowledge is not mentioned, first understand a rough, from the actual use of aspects, combined in the actual use process
Knowledge of computer networks, able to understand the role of socket in the entire TCP/IP protocol stack.

socket and socketserver modules can be used to write network programs, but the difference is that socketserver saves a lot of trouble and you can focus on it
Business logic, regardless of the details of socket, including but not limited to multi-threaded/multi-process, receiving data, sending data, communication process.

The above is Python Socket programming details, more about Python Socket programming information please pay attention to other related articles on this site!


Related articles: