当前位置: 代码迷 >> 综合 >> Unity 与 Python 实现TCP通讯
  详细解决方案

Unity 与 Python 实现TCP通讯

热度:30   发布时间:2023-11-10 16:49:22.0

前言:
由于最近在做一个项目,要使用到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 copyclass Server():def __init__(self):self.tcpServer = Noneself.networkSession = Noneself.clientNum = 0    self.strMsg = 'nihaonihaonihao'self.shutFlag =Falsedef buildServer(self):      #初始化Servermanager = 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):#这里初始的是本机ipif 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()returnfor ipAddress in QNetworkInterface.allAddresses():if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0:breakelse: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 += 1self.shutFlag =Truedef sendData(self):#简单的发送stringif 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 =0print("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 membersprivate TcpClient socketConnection;#endregionconst 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);}}
}

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

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

  相关解决方案