08. 并发TCP服务器

发布时间 2023-11-06 17:40:12作者: 星河映梦

一、并发TCP服务器

  我们使用线程的方式实现并发 TCP 服务器。

from socket import socket
from socket import AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
from time import ctime
from threading import Thread

HOST = "127.0.0.1"
PORT = 8080
ADDRESS = (HOST, PORT)

tcp_server = socket(AF_INET, SOCK_STREAM)               # 创建服务器套接字
tcp_server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)      # 解决端口占用问题
tcp_server.bind(ADDRESS)                                # 套接字与地址绑定
tcp_server.listen(5)                                    # 监听连接,最大挂起连接数为5

class TCPServer(Thread):
    def run(self):
        print("waiting for connection...")

        while True:                                     # 监听连接
            connection, address = tcp_server.accept()   # 接收客户端连接
            print("...connection from: ", address)

            # 创建一个新的子线程,专门为刚刚创建的客户端服务
            handle_data_thread = HandleData(connection, address)
            handle_data_thread.start()

    def __del__(self):
        tcp_server.close()                              # 关闭服务器套接字

class HandleData(Thread):
    def __init__(self, connection, address):
        super().__init__()
        self.connection = connection
        self.address = address

    def run(self):
        while True:                                     # 通信循环
            try:
                recv_data = self.connection.recv(1024)  # 服务端接收消息,单次最大接收为1024个字节
                # 在Linux系统中,一旦data收到空,意味着是一种异常的行为:客户端非法断开连接
                if not recv_data:                       # 适用于Linux系统
                    break
                print(f"收到客户端【{self.address}】发送的数据:{recv_data.decode('utf-8')}")
                self.connection.send(f"【{ctime()}】 {recv_data.decode('utf-8')}".encode("utf-8"))  # 服务端发送消息
            except ConnectionResetError:                # 适用于Windows系统
                break

        print(f"客户端【{self.address}】断开连接!")
        self.connection.close()                         # 关闭连接

if __name__ == "__main__":
    server = TCPServer()
    server.start()

二、TCP服务器

from socket import socket
from socket import AF_INET, SOCK_STREAM

HOST = "127.0.0.1"
PORT = 8080
ADDRESS = (HOST, PORT)

tcp_client = socket(AF_INET, SOCK_STREAM)               # 创建客户端套接字
tcp_client.connect(ADDRESS)                             # 尝试连接服务器

while True:                                             # 通信循环
    send_data = input("请输入要发送的数据: ").strip()
    if not send_data:                                   # 按空格、回车等键结束连接
        break
    tcp_client.send(send_data.encode("utf-8"))          # 客户端发送数据,不允许发送空数据

    recv_data = tcp_client.recv(1024)                   # 客户端接收数据,单次最大接收为1024个字节
    if not recv_data:
        break
    print(f"收到服务端【{ADDRESS}】返回的数据:{recv_data.decode('utf-8')}")

tcp_client.close()                                      # 关闭客户端套接字