Unity 与 Python 实现TCP通讯

前言:
        由于最近在做一个项目,要使用到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);
        }
    }
}

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

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

你可能感兴趣的:(QT,Sofware)