添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
# 开启TCP服务,监听连接到本机 12345 端口的数据 tcp_server = socket . socket ( socket . AF_INET , socket . SOCK_STREAM ) tcp_server . bind ( tcp_addr ) tcp_server . listen () print ( f "TCP server, listening { tcp_addr } " ) # 获取一条来自客户端的请求数据 client_conn , client_addr = tcp_server . accept () data = client_conn . recv ( 10240 ) . decode ( "utf-8" ) print ( f "Received TCP client data: { data } " ) # 关闭TCP服务 tcp_server . close () print ( f "TCP server, has closed." )
  • "0.0.0.0" 表示建立的TCP服务接收来自所有IPV4地址的请求
  • AF_INET 表示 Address Family 中的IPV4协议,同理 AF_INET6 表示IPV6协议
  • SOCK_STREAM 表示我们建立的是TCP连接,同理 SOCK_DGRAM 是UDP连接
  • 建立TCP客户端

    如果需要使用Python通过TCP协议发送数据,与上面类似,也分为三步

  • 创建一个 socket 对象作为TCP client,并连接到指定的TCP服务器(服务器IP和端口)
  • 向TCP服务器请求发送或接收数据
  • 实例化如下 client.py

    Python
     1
    14
    import socket
    # 连接到本机的12345端口
    tcp_addr = ("127.0.0.1", 12345)
    # 建立与服务端的TCP连接
    tcp_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_client.connect(tcp_addr)
    # 注意发送的数据必须是字节流,一般使用UTF-8格式
    tcp_client.sendall("hello world".encode("utf-8"))
    # 关闭与服务端的TCP连接
    tcp_client.close()
    

    同时处理多个客户端请求

    如果需要TCP服务端同时处理多个客户端的请求,可以采取多线程的方式,对于一段时间不活动的客户端连接,可以主动关闭连接节省系统资源,代码实现如下

    Python
    import signal
    import socket
    import threading
    import time
    import typing
    def handle_sigterm(*args):
        """接收中断信号,安全关闭tcp连接"""
        raise KeyboardInterrupt()
    class TcpServer(object):
        def __init__(self, host: str = "0.0.0.0", port: int = 12345, timeout: int = 60):
            self.host = host
            self.port = port
            self.timeout = timeout
            self._addr = (host, port)
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.connections = dict()
        def start(self):
            try:
                signal.signal(signal.SIGTERM, handle_sigterm)
                self._start()
            except KeyboardInterrupt:
                self.server.close()
                print(f"TCP server closed, bye.")
        def _start(self):
            self.server.bind(self._addr)
            self.server.listen()
            print(f"TCP server started, listening on {self._addr}")
            while True:
                client_conn, client_addr = self.server.accept()
                print(f"New TCP client connected, address: {client_addr}")
                client_thread = threading.Thread(
                    target=self._handle_new_client, args=(client_conn, client_addr)
                client_thread.start()
                self.connections[client_addr] = client_thread
        def _handle_new_client(
                self, client_socket: socket.socket, client_addr: typing.Tuple[str, int]
            last_communication = time.time()
            while time.time() - last_communication < self.timeout:
                if data := client_socket.recv(10240).decode("utf-8"):
                    print(f"New data from client {client_addr}: {data}")
                    last_communication = time.time()
                else:
                    time.sleep(1)
            client_socket.close()
            print(f"TCP client {client_addr} closed due to timeout")
            self.connections.pop(client_addr)
    if __name__ == "__main__":
        tcp_server = TcpServer()
        tcp_server.start()
    
  • Socket Programming in Python (Guide) – Real Python
  • How to Create Socket Server with Multiple Clients in Python
  • sockets - What is AF_INET, and why do I need it? - Stack Overflow
  •