# 开启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连接
如果需要使用Python通过TCP协议发送数据,与上面类似,也分为三步
创建一个
socket
对象作为TCP client,并连接到指定的TCP服务器(服务器IP和端口)
向TCP服务器请求发送或接收数据
实例化如下
client.py
Python
|
|
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
|
|