Unity 与 Python 实现TCP通讯

10 篇文章 2 订阅

前言:
        由于最近在做一个项目,要使用到python和Unity 进行TCP通讯,这里介绍以Python端为Server,unity端为Client的例子。

Server:

        服务端使用的是PyQt中的QTcpServer,用Qt的机制可以实现比较高的效率。
        代码如下:
#PyQT5
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtNetwork import *
import string
import copy


class Server():
  
    def __init__(self):
  
        self.tcpServer = None
        self.networkSession = None
      
        self.clientNum = 0    
        self.strMsg = 'nihaonihaonihao'
        self.shutFlag =False

    def buildServer(self):      #初始化Server

        manager = QNetworkConfigurationManager()

        if manager.capabilities() & QNetworkConfigurationManager.NetworkSessionRequired:
            settings = QSettings(QSettings.UserScope, 'QtProject')
            settings.beginGroup('QtNetwork')
            id = settings.value('DefaultNetworkConfiguration', '')
            settings.endGroup()
  
            config = manager.configurationFromIdentifier(id)
            if config.state() & QNetworkConfiguration.Discovered == 0:
                config = manager.defaultConfiguration()
  
            self.networkSession = QNetworkSession(config, self)
            self.networkSession.opened.connect(self.sessionOpened)
  
            self.statusLabel.setText("Opening network session.")
            self.networkSession.open()
        else:
            self.sessionOpened()
  
        self.tcpServer.newConnection.connect(self.ClientInit)   #有新的client就链接到新client上进行通讯

    def sessionOpened(self):#这里初始的是本机ip

        if self.networkSession is not None:
            config = self.networkSession.configuration()
  
            if config.type() == QNetworkConfiguration.UserChoice:
                id = self.networkSession.sessionProperty('UserChoiceConfiguration')
            else:
                id = config.identifier()
  
            settings = QSettings(QSettings.UserScope, 'QtProject')
            settings.beginGroup('QtNetwork')
            settings.setValue('DefaultNetworkConfiguration', id)
            settings.endGroup();
  
        self.tcpServer = QTcpServer()
        self.tcpServer.listen(QHostAddress.Any,50213)

        if self.tcpServer.isListening() == False:
            QMessageBox.critical(self, "Fortune Server",
                    "Unable to start the server: %s." % self.tcpServer.errorString())
            self.close()
            return
  
        for ipAddress in QNetworkInterface.allAddresses():
            if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0:
                break
        else:
            ipAddress = QHostAddress(QHostAddress.LocalHost)

        print(ipAddress.toString())
        print(self.tcpServer.serverPort())

        self.ipAddress =ipAddress.toString()
        self.ipPort = self.tcpServer.serverPort()
        
    def ClientInit(self):#有新的client就链接新的client并和其通讯

        if self.clientNum ==1:

            self.serverShutCurrentClient()
            print("Sudden client builds the connection")
        

        if self.clientNum==0:

            print("New client builds the connection")
            self.clientConnection = self.tcpServer.nextPendingConnection()
            self.clientConnection.disconnected.connect(self.serverShutCurrentClient)
            self.clientConnection.readyRead.connect(self.readData)
            self.clientNum += 1
            self.shutFlag =True

    def sendData(self):#简单的发送string

        if self.clientNum == 1:

            block = QByteArray()        
            block.append(self.strMsg)         
            self.clientConnection.write(block)
            

    def readData(self):#简单的读取string,并除去byte标符

        tempdata = self.clientConnection.read(1024)
        tempstr = str(tempdata)        
        tempstr = tempstr.replace("b'",'')
        tempstr = tempstr.replace("'",'')

        print(tempstr)


    def serverShutCurrentClient(self):#client通讯断开执行

        self.clientConnection.disconnectFromHost()
        self.clientNum =0
        print("Disconnect with the last client")
        
    def serverShutDown(self):#Server 断开执行
        if self.shutFlag :
            self.clientConnection.close()
        print("The Server is shut down!")
以上是比较简单的基于PyQt5的demo


Unity Client:

       以下是基于C#的client类,这个demo没有使用线程,使用的是回掉函数来进行读取操作:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using System.Net.Sockets;
using System.Text;
using System;


public class TCPSocket  {

    #region private members
    private TcpClient socketConnection;

    #endregion

    const int RevSize = 1024;
    const int SenfSize = 1024;
    public byte[] RevBuffer = new byte[RevSize];
    public byte[] SendBuffer = new byte[SenfSize];
    string strMesg = string.Empty;


    public void TCPSocketQuit() {       //断开链接

        socketConnection.Close();


        Debug.Log("TCP Client has quitted!");

    }

     public void Connect2TcpServer() {   //链接初始化,同时使用回调函数

        try
        {
            socketConnection = new TcpClient("192.168.1.103", 50213);
            socketConnection.GetStream().BeginRead(RevBuffer, 0, RevSize, new AsyncCallback(Listen4Data), null);

            Debug.Log("TCP Client connected!");
        }
        catch{

            Debug.Log("Open thread for build client is error!  ");

        }

    }

     public void Listen4Data(IAsyncResult ar) {//此为回调函数

        int BytesRead;

        try
        {
            BytesRead = socketConnection.GetStream().EndRead(ar);

            if (BytesRead < 1)
            {
         
                Debug.Log("Disconnected");
                return;
            }

            strMesg = Encoding.Default.GetString(RevBuffer, 0, BytesRead );
            Debug.Log(strMesg);

            socketConnection.GetStream().BeginRead(RevBuffer, 0, RevSize, new AsyncCallback(Listen4Data), null);//再次使用回掉函数

        }
        catch {
            Debug.Log("Disconnected");
        }


    }

     public void SendMessage()//简单的发送数据
    {
        if (socketConnection == null)
        {
            return;
        }
        try
        {		
            NetworkStream stream = socketConnection.GetStream();

            if (stream.CanWrite)
            {
                string clientMessage = "This is a message from one of your clients.";
            
                byte[] clientMessageAsByteArray = Encoding.ASCII.GetBytes(clientMessage);

                stream.Write(SendBuffer, 0, 4);
                
            }
        }
        catch (SocketException socketException)
        {
            Debug.Log("Socket exception: " + socketException);
        }
    }
}

以上就为通讯的两个方面,依照一定协议,就可以互相通讯数据。这里只是项目最简单的通讯部分。

由于时间原因,只做了简单的注释,有误希望指出。

  • 7
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Unity中使用Python进行TCP通信,可以通过以下步骤实现: 1. 编写Python脚本实现TCP服务器或客户端功能。 2. 在Unity项目中添加Python脚本,并使用Python.NET库将Python脚本导入到Unity中。 3. 在Unity中调用Python脚本,实现TCP通信功能。 下面是一个简单的示例,演示了如何在Unity中使用Python实现TCP客户端通信: 1. 编写Python脚本 ``` import socket TCP_IP = '127.0.0.1' TCP_PORT = 5005 BUFFER_SIZE = 1024 MESSAGE = "Hello, World!" s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((TCP_IP, TCP_PORT)) s.send(MESSAGE.encode()) data = s.recv(BUFFER_SIZE) s.close() print("received data:", data.decode()) ``` 这个脚本会连接到一个指定的IP地址和端口,发送一条消息并接收回复。 2. 导入Python脚本到Unity中 在Unity项目中,需要使用Python.NET库将Python脚本导入到C#脚本中。可以从NuGet包管理器中安装Python.NET,也可以手动下载并添加到项目中。 在C#脚本中,可以使用以下代码导入Python脚本: ``` using System; using Python.Runtime; public class PythonClient : MonoBehaviour { void Start() { // Initialize Python runtime PythonEngine.Initialize(); // Import Python script using (Py.GIL()) { dynamic client = Py.Import("tcp_client"); client.main(); } // Shutdown Python runtime PythonEngine.Shutdown(); } } ``` 这个脚本会初始化Python运行时,导入Python脚本并调用其中的`main`函数。 3. 在Unity中调用Python脚本 在需要使用TCP通信的地方,可以使用以下代码调用Python脚本: ``` using System; using Python.Runtime; public class MyComponent : MonoBehaviour { void Start() { using (Py.GIL()) { dynamic client = Py.Import("tcp_client"); client.main(); } } } ``` 这个脚本会在Unity中调用Python脚本的`main`函数,实现TCP通信功能。 需要注意的是,在Unity中使用Python进行TCP通信时,需要确保Python脚本和Unity项目使用的Python版本一致,否则可能会出现错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值