unity开发:Qt C++与unity之间UDP网络通信

再试试UDP通信,发送速度快,更加灵活

UDP实际相当于是对等通信,不用简历连接,,但是这里为了有个server的概念,在服务端绑定了端口,而客户端则是发送时随机分配的端口

Qt C++服务端

简历gui工程,pro里面加入network模块,界面放一个label,两个button

widget.h

#ifndef WIDGET_H#define WIDGET_H#include <QWidget>#include <QUdpSocket>namespace Ui {class Widget;}class Widget : public QWidget{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();private:Ui::Widget *ui;private:QString statusText; //状态信息QUdpSocket *udpSocket; //套接字QHostAddress clientIp; //客户端ipquint16 clientPort; //客户端portvoid SocketSend(QString sendStr,QHostAddress targetIp,quint16 targetPort); //发送数据,可以向指定目标发送,或者广播private slots:void ProcessPendingDatagram(); //当接收到数据时作出响应void on_leftBtn_clicked();void on_rightBtn_clicked();};#endif // WIDGET_H

widget.cpp

#include "widget.h"#include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget){ui->setupUi(this);//初始化udpudpSocket=new QUdpSocket(this);udpSocket->bind(QHostAddress::Any,8888);//绑定ip和端口,可以是Any,LocalHost//label显示状态statusText=statusText+"wait for connecting…"+"\n";ui->statusLabel->setText(statusText);//绑定信号槽,当接收到数据时作出反应connect(udpSocket,SIGNAL(readyRead()),this,SLOT(ProcessPendingDatagram()));}void Widget::ProcessPendingDatagram(){//等待数据接收完毕再做处理while(udpSocket->hasPendingDatagrams()){QByteArray recvData;recvData.resize(udpSocket->pendingDatagramSize());udpSocket->readDatagram(recvData.data(),recvData.size(),&clientIp,&clientPort); //从发送方的包中读取数据以及ip和port并赋值给类的变量statusText+="connet from "+clientIp.toString()+":"+QString::number(clientPort)+" ";statusText+=recvData+"\n";//显示到状态标签ui->statusLabel->setText(statusText);//转发回去SocketSend("from server:"+recvData,clientIp,clientPort);}}void Widget::SocketSend(QString sendStr,QHostAddress targetIp,quint16 targetPort){udpSocket->writeDatagram(sendStr.toStdString().c_str(),sendStr.length(),targetIp,targetPort);}Widget::~Widget(){delete ui;}//unity物体左旋void Widget::on_leftBtn_clicked(){SocketSend("leftrotate",clientIp,clientPort);}//unity物体右旋void Widget::on_rightBtn_clicked(){SocketSend("rightrotate",clientIp,clientPort);}

main.cpp未更改,不贴了

unity C#客户端

同样是吧udp socket部分封装成了一个类,加到另外一个类里面,挂到场景里

UdpClientHandler.cs

using UnityEngine;using System.Collections;//引入库using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;public class UdpClientHandler:MonoBehaviour{//以下默认都是私有的成员Socket socket; //目标socketEndPoint serverEnd; //服务端IPEndPoint ipEnd; //服务端端口string recvStr; //接收的字符串string sendStr; //发送的字符串byte[] recvData=new byte[1024]; //接收的数据,必须为字节byte[] sendData=new byte[1024]; //发送的数据,必须为字节int recvLen; //接收的数据长度Thread connectThread; //连接线程//初始化public void InitSocket(){//定义连接的服务器ip和端口,可以是本机ip,局域网,互联网ipEnd=new IPEndPoint(IPAddress.Parse("127.0.0.1"),8888);//定义套接字类型,在主线程中定义socket=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);//定义服务端IPEndPoint sender=new IPEndPoint(IPAddress.Any,0);serverEnd=(EndPoint)sender;print("waiting for sending UDP dgram");//建立初始连接,这句非常重要,第一次连接初始化了serverEnd后面才能收到消息SocketSend("hello");//开启一个线程连接,必须的,否则主线程卡死connectThread=new Thread(new ThreadStart(SocketReceive));connectThread.Start();}public void SocketSend(string sendStr){//清空发送缓存sendData=new byte[1024];//数据类型转换sendData=Encoding.ASCII.GetBytes(sendStr);//发送给指定服务端socket.SendTo(sendData,sendData.Length,SocketFlags.None,ipEnd);}//服务器接收void SocketReceive(){//进入接收循环while(true){//对data清零recvData=new byte[1024];//获取客户端,获取服务端端数据,用引用给服务端赋值,实际上服务端已经定义好并不需要赋值recvLen=socket.ReceiveFrom(recvData,ref serverEnd);print("message from: "+serverEnd.ToString()); //打印服务端信息//输出接收到的数据recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);print(recvStr);}}//返回接收到的字符串public string GetRecvStr(){string returnStr;//加锁防止字符串被改lock(this){returnStr=recvStr;}return returnStr;}//连接关闭public void SocketQuit(){//关闭线程if(connectThread!=null){connectThread.Interrupt();connectThread.Abort();}//最后关闭socketif(socket!=null)socket.Close();}}UdpTest.csusing UnityEngine;using System.Collections;public class UdpTest:MonoBehaviour{string editString="hello wolrd"; //编辑框文字GameObject cube;UdpClientHandler udpClient;// Use this for initializationvoid Start(){//初始化网络udpClient=gameObject.AddComponent<UdpClientHandler>();udpClient.InitSocket();//找到cubecube=GameObject.Find("Cube");}void OnGUI(){editString=GUI.TextField(new Rect(10,10,100,20),editString);GUI.Label(new Rect(10,30,300,20),udpClient.GetRecvStr());if(GUI.Button(new Rect(10,50,60,20),"send"))udpClient.SocketSend(editString);}// Update is called once per framevoid Update(){if(udpClient.GetRecvStr()!=null){switch(udpClient.GetRecvStr()){case "leftrotate":cube.transform.Rotate(Vector3.up,50*Time.deltaTime);break;case "rightrotate":cube.transform.Rotate(Vector3.down,50*Time.deltaTime);break;}}}void OnApplicationQuit(){//退出时关闭连接udpClient.SocketQuit();}}测试

依然是服务端和客户端之间互相收发消息,服务端可以控制客户端里面的cube旋转

不要等待机会,而要创造机会。

unity开发:Qt C++与unity之间UDP网络通信

相关文章:

你感兴趣的文章:

标签云: