Python Socket module realizes communication between server and client

Socket is an external programming interface provided by TCP/IP , which is the encapsulation and application of TCP/IP.

Socket is called "socket" and is used to describe IP addresses and ports . It is a communication and chain handle, which can realize communication between different virtual machines or different computers. Two programs on the network exchange data through a two-way communication connection, and the application program sends a request to the network or responds to a network request through a "socket".

The main purpose of the Socket module is to help establish a channel of information between two programs on the network. Two basic Socket modules are provided in Python: server-side Socket and client-side Socket .

When a server Socket is created, the Socket will wait for a connection on a port of the machine , and the client Socket will access this port. After the two complete the connection, they can interact.

Write a simple server and client using Socket

Multithreaded server program:

# -*- coding: UTF-8 -*-
import socket               # 导入 socket 模块
import threading

# 处理客户端的请求操作
def handle_client_request(service_client_socket, ip_port):
    # 循环接收客户端发送的数据
    while True:
        # 接收客户端发送的数据
        recv_data = service_client_socket.recv(1024)
        # 容器类型判断是否有数据可以直接使用if语句进行判断,如果容器类型里面有数据表示条件成立,否则条件失败
        # 容器类型: 列表、字典、元组、字符串、set、range、二进制数据
        if recv_data:
            message = recv_data.decode()
            print(message)
            print(ip_port)
            # 回复
            service_client_socket.send("已接收...".encode())
 
        else:
            print("客户端下线了:", ip_port)
            print()
            break
    # 终止和客户端进行通信
    service_client_socket.close()
 
if __name__ == '__main__':
    # 创建tcp服务端套接字
    tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置端口号复用,让程序退出端口号立即释放
    tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号
    tcp_server_socket.bind(("", 9090))
    # 设置监听, listen后的套接字是被动套接字,只负责接收客户端的连接请求
    tcp_server_socket.listen(128)
    # 循环等待接收客户端的连接请求
    while True:
        # 等待接收客户端的连接请求
        service_client_socket, ip_port = tcp_server_socket.accept()
        print("客户端连接成功:", ip_port)
        # 当客户端和服务端建立连接成功以后,需要创建一个子线程,不同子线程负责接收不同客户端的消息
        sub_thread = threading.Thread(target=handle_client_request, args=(service_client_socket, ip_port))
        # 设置守护主线程
        sub_thread.setDaemon(True)
        # 启动子线程
        sub_thread.start()
 
    # tcp服务端套接字可以不需要关闭,因为服务端程序需要一直运行
    # tcp_server_socket.close()

Client program:

# -*- coding: UTF-8 -*-
import socket               # 导入 socket 模块

if __name__ == '__main__':
    sk = socket.socket()         # 创建 socket 对象

    host = socket.gethostname() # 获取本地主机名
    port = 9090                # 设置端口号

    sk.connect((host, port))
    message = "connect······"
    sk.sendall(message.encode())
    print(sk.recv(1024).decode())

    i = 0
    while True:
        try:
            message = input(">>>")
            sk.send(message.encode())
            print(sk.recv(1024).decode())
        except KeyboardInterrupt:
            break
        
    sk.close()

operation result:
insert image description here

Socket instantiation

Format:

sk = socket.socket(family,type[,protocal])

family : address family, commonly used address families are AF_INET, AF_INET6, AF_LOCAL (or AF_UNIX, UNIX domain Socket), AF_ROUTE, etc. The default is AF_INET, usually you can use the default.

type : Socket type
SOCK_STREAM, TCP type (default)
SOCK_DGRAM, UDP type
SOCK_RAM, original type, allowing direct access to underlying protocols such as IP or ICMP, basically not used.

protocol : optional, the protocol used, usually assigned the value "0", automatically selected by the system.

Socket common functions

  1. bind()
    is called by the server Socket to bind the previously created Socket to the specified IP address and port.
sk.bind(("127.0.0.1",9090))
  1. listen() is used to enable the listening mode on the server
    using TCP .
#服务端开启一个监听,最大连接数为5
sk.listen(128)
  1. accept() is used to receive connections on the server side
    using TCP , generally in a blocking state. Accept the TCP connection and return (conn, adress), where conn is a new socket object that can be used to receive and send data, and address is the address of the connected client.
socket_new, port = sk.accept()
  1. connect() is used when the client
    using TCP connects to the server
sk.connect(("127.0.0.1", 9090))
  1. send()
    is used to send data when using TCP, and may not send all the specified content.
sk.send(string[,flag])   #返回值是发送字节数量
  1. sendall()
    is used to send data when using TCP, and send TCP data completely .
# 发送一段字符到Socket
sk.sendall("Hello!".encode())
# 成功返回None,失败抛出异常 
  1. recv()
    is used to receive data using TCP.
sk.recv(bufsize[,flag])
# bufsize指定最多可以接收的数量
  1. sendto() is used to send data when
    using UDP

  2. recvfrom()
    is dedicated to UDP , receives data, and returns the remote IP address and port

  3. close()
    closes the Socket

Guess you like

Origin blog.csdn.net/qq_43619058/article/details/125114332