You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过网络实现Python脚本间通信?含跨版本Socket重连问题

问题分析与解决方案

核心问题

你的服务端当前仅处理一次客户端连接,处理完成后就退出了,没有回到监听状态等待新连接;同时客户端的连接逻辑是自动发送10次数据后关闭,不符合“手动断开”的需求,且按钮变量名存在错误导致GUI功能异常。

服务端修改(Python3)

将服务端改为循环监听模式,处理完一个客户端连接后自动回到监听状态,同时持续向客户端发送数据直到对方断开:

import socket
import time

HOST = "127.0.0.1"
PORT = 65432

# 创建并绑定socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen()
print(f"服务端已启动,监听 {HOST}:{PORT}")

while True:
    # 等待新连接
    conn, addr = s.accept()
    print(f"已连接客户端: {addr}")
    
    try:
        # 持续向客户端发送数据,直到客户端断开
        count = 0
        while True:
            send_data = f"服务端发送数据: {count}".encode('utf-8')
            conn.sendall(send_data)
            print(f"已发送: {send_data.decode('utf-8')}")
            count += 1
            time.sleep(1)
            
            # 尝试接收客户端数据(检测是否断开)
            conn.settimeout(0.5)
            try:
                data = conn.recv(1024)
                if not data:
                    break
                print(f"收到客户端回复: {data.decode('utf-8')}")
            except socket.timeout:
                continue
    except ConnectionResetError:
        print(f"客户端 {addr} 强制断开连接")
    finally:
        conn.close()
        print(f"与客户端 {addr} 的连接已关闭,等待新连接...")

修改说明

  • 外层while True循环:让服务端处理完一个连接后,重新调用s.accept()等待新连接
  • 内部发送循环:持续向客户端发送数据,通过recv超时检测客户端是否断开
  • 异常处理:捕获ConnectionResetError处理客户端强制断开的情况

客户端修改(Python2.7)

修正GUI变量错误,实现“手动连接/断开”功能,用后台线程处理socket通信避免卡住GUI:

import Tkinter as tk
import socket
import random
import time
import threading

keyState = False
HOST = '127.0.0.1'
PORT = 65432
client_socket = None  # 全局保存socket实例
stop_flag = False     # 控制发送线程的停止信号

def onButton():
    global keyState 

    if not keyState:
        keyState = True
        softkey_button.config(relief='sunken')
        # 启动连接线程,避免阻塞GUI
        threading.Thread(target=connectSocket, daemon=True).start()
        print(keyState)
    else:
        keyState = False
        softkey_button.config(relief='raised')
        disconnectSocket()
        print(keyState)

def connectSocket():
    global client_socket, stop_flag
    print("connectSocket()")
    stop_flag = False
    
    try:
        client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        client_socket.connect((HOST, PORT))
        print("已连接到服务端")
        
        # 持续接收服务端数据,直到断开
        while not stop_flag:
            try:
                data = client_socket.recv(1024)
                if not data:
                    print("服务端已断开连接")
                    break
                print 'Received', repr(data)
            except socket.error:
                break
    except Exception as e:
        print(f"连接失败: {str(e)}")
        keyState = False
        softkey_button.config(relief='raised')
    finally:
        if client_socket:
            client_socket.close()

def disconnectSocket():
    global client_socket, stop_flag
    print("disconnectSocket()")
    stop_flag = True
    if client_socket:
        try:
            client_socket.close()
            print("已断开与服务端的连接")
        except:
            pass

#Main GUI
root = tk.Tk()
root.title('Python Socket Test')
root.configure(background='white')
root.geometry("200x300")

#Button
softkey_button = tk.Button(root, text="Softkey", command=onButton, relief='flat')
softkey_button.place(x=75,y=200)

root.mainloop()

修改说明

  • 全局变量client_socket:保存socket实例,方便断开时关闭
  • 后台线程处理连接:避免socket通信阻塞Tkinter GUI主线程
  • stop_flag:控制接收线程的停止,实现手动断开功能
  • 修正按钮变量名:将错误的key_button改为实际的softkey_button
  • 完善断开逻辑:在disconnectSocket中主动关闭socket并停止接收线程

测试步骤

  1. 先启动服务端,会显示“服务端已启动,监听...”
  2. 启动客户端,点击按钮连接,会收到服务端持续发送的数据
  3. 再次点击按钮断开连接,服务端会显示连接关闭并等待新连接
  4. 可以多次点击客户端按钮实现连接/断开,服务端都会正常处理

内容的提问来源于stack exchange,提问作者JNDStackOverflow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 05:55:30