Socket library: Python implements TCP/IP client and server communication

table of Contents

Preface

In addition to functions such as analyzing network addresses, sockets can also be configured with a server to monitor incoming messages.

For example, if you chat with a network robot on the Internet, you send data to the robot (server), and then the robot (server) sends back the chat data to you.

Of course, the robot's reply may also involve machine learning, but simple message feedback involves the knowledge of sockets.

Simple build server and client

Now that you have understood the application of sockets. Next, let's implement a simple one-way communication between TCP/IP server and client.

server

The principle of the server is as follows:

  1. First create a socket, TCP is a stream-oriented socket. So you need to use SOCK_STREAM
  2. Then use the bind() function to associate the socket with the server address (because we are only testing locally, directly set the address to 127.0.0.1 or localhost, and the port number is 10000). Of course, if you have 2 computer devices around you, you can Directly replace the IP address of the LAN
  3. Call the listen() function to set the socket to server mode, and then wait in an infinite loop, the parameter is the maximum number of queues
  4. In the loop, call accept() to wait for the client's message connection. If there is a client connection, then the accept() function will return an open connection and the client address
  5. Specify a buffer, the buffer is used to store the data received by the recv function
  6. Send back client data through sendall()
  7. After the data is returned, the communication with the current client is complete. Need to use close() to close and clean up

The sample code is as follows:

import socket

# 1.创建一个套接字,
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2.使用bind()函数将套接字与服务器地址关联
sock.bind(('localhost', 10000))
# 3.调用listen()函数将套接字设置为服务器模式
sock.listen(1)

while True:
    # 4.调用accept()等待客户端的消息连接
    # 如果有客户端进行连接,那么accept()函数会返回一个打开的连接与客户端地址
    connection, client_address = sock.accept()
    print("连接客户端地址:", client_address)
    try:
        # 5.指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据
        data = connection.recv(1024)
        print(data)
        if data:
            # 6.通过sendall()进行回传客户端数据。
            connection.sendall("已接受到数据".encode())
        else:
            print("客户端没有发送数据,不需要传送数据")
    finally:
        #7.需要使用close()进行关闭清理
        connection.close()

Client

Realizing the client is relatively simpler than the server, because it does not need to monitor, only need to connect to send data. The client implementation is mainly divided into:

  1. Create a socket
  2. Use the connect() function to connect to the server
  3. Send data to the server through sendall()
  4. Accept the data sent back by the server through recv()
  5. After the interaction is complete, use close() to close the cleanup

Examples are as follows:

import socket

# 1.创建一个套接字,
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2.使用bind()函数将套接字与服务器地址关联
sock.connect(('localhost', 10000))

try:
    msg = b"Are you there?"
    # 3.通过sendall()向服务器发送数据
    sock.sendall(msg)
    # 4.通过recv()接受服务器传递回的数据
    data = sock.recv(1024)
    print(data.decode())
finally:
    # 5.交互完成之后,使用close()关闭清理
    sock.close()

After running, the server and client interaction effects are as follows:

Server data


Client data

create_connection (easier client)

In addition to using the connect() function to connect to the server, there is actually another function create_connection() to connect to the server, which can omit several steps. Examples are as follows:

import socket

# 获取匹配开头字符串的所有属性值
def getConstants(prefix):
    return {
        getattr(socket, n): n
        for n in dir(socket)
        if n.startswith(prefix)
    }
    
ipproto_str = getConstants("IPPROTO_")
family_str = getConstants("AF_")
type_str = getConstants("SOCK_")

sock = socket.create_connection(('127.0.0.1', 10000))
print(ipproto_str[sock.proto])
print(family_str[sock.family])
print(type_str[sock.type])

try:
    msg = b"Are you there?"
    sock.sendall(msg)
    data = sock.recv(1024)
    print(data.decode())
finally:
    sock.close()

After running, the effect is as follows:

Client
The principle of the create_connection() function is to use the getaddrinfo() function to find the parameters of the candidate connection and return an open socket. The explanation of the getaddrinfo() function is in the previous socket library ( click to view ).