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

Python脚本传输桌面画面至Unity时遇WinError 10053连接中止问题

解决ConnectionAbortedError 10053的问题

核心问题分析

出现ConnectionAbortedError: [WinError 10053]的主要原因包括:

  • 字节序不匹配:Python用大端序发送帧长度,Unity默认用系统小端序解析,导致帧大小计算错误,引发数据读取异常
  • Unity端内存泄漏:每次接收帧都创建新Texture2D,未回收旧资源,长期运行导致性能下降
  • 发送频率过高:Python无间隔发送帧,Unity处理速度跟不上,导致网络缓冲区溢出
  • 异常处理不完整:两端未处理连接断开等异常,导致资源未正确释放

修复后的代码

Python服务端

import socket
import cv2
import numpy as np
from PIL import ImageGrab
import time

# Set up the server
server_ip = 'Insert IP Here'  
server_port = Insert Port Here  

# Create a socket object
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Bind the socket to the address
server_socket.bind((server_ip, server_port))

# Listen for incoming connections
server_socket.listen(1)

print("Waiting for Unity application to connect...")

# Accept incoming connection
connection, address = server_socket.accept()
print("Connected to Unity application at", address)

# Function to capture desktop frames and send them over the network
def send_frames():
    try:
        while True:
            # Capture desktop frame
            frame = capture_screen()

            # 统一用小端序发送帧长度,和Unity端匹配
            frame_size = len(frame)
            connection.sendall(frame_size.to_bytes(4, byteorder='little'))

            # Send frame data
            connection.sendall(frame)

            # 控制发送频率,避免Unity处理不过来(比如30帧/秒)
            time.sleep(1/30)

    except (KeyboardInterrupt, ConnectionResetError, BrokenPipeError):
        print("Connection closed.")
    finally:
        connection.close()
        server_socket.close()

def capture_screen():
    # Capture desktop screen using OpenCV
    screen = cv2.cvtColor(np.array(ImageGrab.grab()), cv2.COLOR_RGB2BGR)
    
    # 降低JPG质量,减少传输数据量(可根据需求调整,0-100)
    _, frame_encoded = cv2.imencode('.jpg', screen, [int(cv2.IMWRITE_JPEG_QUALITY), 70])
    return frame_encoded.tobytes()

if __name__ == "__main__":
    send_frames()

Unity客户端

using UnityEngine;
using System;
using TMPro;
using System.Net.Sockets;
using System.Threading.Tasks;

public class ScreenMirror : MonoBehaviour
{
    public Material planeMaterial;
    public string serverIp = "Insert IP Here";
    public int serverPort = Insert Port Here;
    public TMP_Text networkStatusText;

    private TcpClient client;
    private NetworkStream stream;
    private bool receiving = false;
    private const int bufferSize = 1024 * 1024; // 1 MB buffer size
    private Texture2D texture; // 复用Texture2D,避免内存泄漏

    private async void Start()
    {
        try
        {
            client = new TcpClient();
            await client.ConnectAsync(serverIp, serverPort);
            stream = client.GetStream();
            receiving = true;
            networkStatusText.text = "Connected";

            // 初始化Texture2D
            texture = new Texture2D(1, 1);

            // Start receiving frames asynchronously
            await ReceiveFramesAsync();
        }
        catch (Exception e)
        {
            Debug.LogError("Error connecting to server: " + e.Message);
            networkStatusText.text = "Error: " + e.Message;
        }
    }

    private async Task ReceiveFramesAsync()
    {
        try
        {
            byte[] buffer = new byte[bufferSize];

            while (receiving)
            {
                // Read frame size
                int bytesRead = await stream.ReadAsync(buffer, 0, 4);
                if (bytesRead != 4)
                {
                    Debug.LogWarning("Incomplete frame size received.");
                    break;
                }

                // 用小端序解析帧长度,和Python端匹配
                int frameSize = BitConverter.ToInt32(buffer, 0);

                // 检查帧大小是否超过缓冲区限制
                if (frameSize > bufferSize)
                {
                    Debug.LogError($"Frame size {frameSize} exceeds buffer size {bufferSize}");
                    break;
                }

                // Read frame data
                bytesRead = 0;
                while (bytesRead < frameSize)
                {
                    int read = await stream.ReadAsync(buffer, bytesRead, frameSize - bytesRead);
                    if (read == 0)
                    {
                        Debug.LogWarning("Connection closed by server.");
                        break;
                    }
                    bytesRead += read;
                }

                if (bytesRead != frameSize)
                    break;

                // 复用Texture2D加载图片
                if (!texture.LoadImage(buffer))
                {
                    Debug.LogWarning("Failed to load image data.");
                    continue;
                }

                // Apply texture to plane material
                planeMaterial.mainTexture = texture;
            }
        }
        catch (Exception e)
        {
            Debug.LogError("Error receiving frames: " + e.Message);
            networkStatusText.text = "Error: " + e.Message;
        }
        finally
        {
            receiving = false;
            if (stream != null)
                stream.Close();
            if (client != null)
                client.Close();
            // 释放Texture资源
            if (texture != null)
                Destroy(texture);
            networkStatusText.text = "Disconnected";
        }
    }

    private void OnDestroy()
    {
        receiving = false;
    }
}

额外建议

  • 确保Python和Unity使用相同的IP和端口,测试时优先用127.0.0.1(本地回环)排除网络问题
  • 关闭Python和Unity程序后,检查端口是否被占用(可用netstat -ano | findstr 端口号命令)
  • 若仍有问题,暂时关闭防火墙测试(测试后再恢复规则)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 02:35:57