udp unity 通过端口通讯_unity开发:Qt C++与unity其间UDP网络通信

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

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

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

Qt C++服务端

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

widget.h

#ifndef WIDGET_H

#define WIDGET_H

#include

#include

namespace Ui {

class Widget;

}

class Widget : public QWidget

{

Q_OBJECT

public:

explicit Widget(QWidget *parent = 0);

~Widget();

private:

Ui::Widget *ui;

private:

QString statusText; //状态信息

QUdpSocket *udpSocket; //套接字

QHostAddress clientIp; //客户端ip

quint16 clientPort; //客户端port

void 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);

//初始化udp

udpSocket=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; //目标socket

EndPoint 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();

}

//最后关闭socket

if(socket!=null)

socket.Close();

}

}UdpTest.cs

using UnityEngine;

using System.Collections;

public class UdpTest:MonoBehaviour

{

string editString="hello wolrd"; //编辑框文字

GameObject cube;

UdpClientHandler udpClient;

// Use this for initialization

void Start()

{

//初始化网络

udpClient=gameObject.AddComponent();

udpClient.InitSocket();

//找到cube

cube=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 frame

void 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旋转

你可能感兴趣的:(udp,unity,通过端口通讯)