tcp unity 图片_unity做客户端实现TCP网络通信

本文介绍了如何使用Unity作为客户端,通过TCP协议与Qt C++服务器进行网络通信。在Qt C++侧,创建了一个GUI界面,监听6666端口,接收并响应Unity的控制指令。在Unity侧,创建一个场景和cube,通过TcpClientHandler类实现TCP连接,接收服务器指令并控制cube旋转。
摘要由CSDN通过智能技术生成

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

考虑实现用C++做服务器,unity做客户端实现TCP网络通信。

以下采用TCP单线程连接。

Qt C++服务端

建立一个Qt的GUI项目,在界面上放一个label显示连接状态,两个button作为指令发送控制。

记得在pro文件中加入network模块

widget.h

#ifndef WIDGET_H

#define WIDGET_H

#include

class QTcpServer;//前向声明

class QTcpSocket;

namespace Ui {

class Widget;

}

class Widget : public QWidget

{

Q_OBJECT

public:

explicit Widget(QWidget *parent = 0);

~Widget();

private:

Ui::Widget *ui;

private:

QString statusText; //状态信息

QTcpServer *tcpServer; //服务器

QTcpSocket *clientTcpSocket; //客户端socket

void SocketSend(QString sendStr);

private slots:

void SocketConnet();

void SocketReceive();

void on_leftBtn_clicked();

void on_rightBtn_clicked();

};

#endif // WIDGET_H

widget.cpp

#include

#include

#include

#include

#include "widget.h"

#include "ui_widget.h"

Widget::Widget(QWidget *parent) :

QWidget(parent),

ui(new Ui::Widget)

{

ui->setupUi(this);

//初始化server并监听

tcpServer=new QTcpServer(this); //qt自己内存管理

if(!tcpServer->listen(QHostAddress::Any,6666)) //监听所有网络地址,端口6666

qDebug()<errorString();

statusText=statusText+"wait for connecting..."+"\n";

ui->statusLabel->setText(statusText);

//绑定信号槽,当有连接时作出反应

connect(tcpServer,SIGNAL(newConnection()),this,SLOT(SocketConnet()));

}

void Widget::SocketConnet()

{

//获得client socket

clientTcpSocket=tcpServer->nextPendingConnection();

//绑定信号槽,接收数据,并且当连接关闭是删除连接

connect(clientTcpSocket,SIGNAL(readyRead()),this,SLOT(SocketReceive()));

connect(clientTcpSocket,SIGNAL(disconnected()),clientTcpSocket,SLOT(deleteLater()));

//显示客户端连接信息

QString clientIp=clientTcpSocket->peerAddress().toString();

QString clientPort=QString::number(clientTcpSocket->peerPort());

statusText=statusText+"conneted with "+clientIp+":"+clientPort+"\n";

ui->statusLabel->setText(statusText);

}

void Widget::SocketSend(QString sendStr)

{

clientTcpSocket->write(sendStr.toStdString().c_str());

}

void Widget::SocketReceive()

{

//接收数据并显示,字节转换成了字符串

QString recvStr=clientTcpSocket->readAll();

statusText=statusText+recvStr+"\n";

ui->statusLabel->setText(statusText);

//经处理后发送回去

SocketSend("From server: "+recvStr);

}

Widget::~Widget()

{

delete ui;

}

//发送unity物体左旋消息

void Widget::on_leftBtn_clicked()

{

SocketSend("leftrotate");

}

//发送unity物体右旋消息

void Widget::on_rightBtn_clicked()

{

SocketSend("rightrotate");

}

main.cpp未更改就不贴了。

unity C#客户端

建立一个unity场景,拖入一个cube

把tcpsocket连接部分封装成了一个单独的类TcpClientHandler,再加一个脚本TcpTest挂到场景中,在这个脚本中实例化用于连接的TcpClientHandler。

TcpClientHandler.cs

using UnityEngine;

using System.Collections;

//引入库

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Threading;

public class TcpClientHandler:MonoBehaviour

{

Socket serverSocket; //服务器端socket

IPAddress ip; //主机ip

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=IPAddress.Parse("127.0.0.1"); //可以是局域网或互联网ip,此处是本机

ipEnd=new IPEndPoint(ip,6666); //服务器端口号

//开启一个线程连接,必须的,否则主线程卡死

connectThread=new Thread(new ThreadStart(SocketReceive));

connectThread.Start();

}

void SocketConnet()

{

if(serverSocket!=null)

serverSocket.Close();

//定义套接字类型,必须在子线程中定义

serverSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

print("ready to connect");

//连接

serverSocket.Connect(ipEnd);

//输出初次连接收到的字符串

recvLen=serverSocket.Receive(recvData);

recvStr=Encoding.ASCII.GetString(recvData,0,recvLen);

print(recvStr);

}

public void SocketSend(string sendStr)

{

//清空发送缓存

sendData=new byte[1024];

//数据类型转换

sendData=Encoding.ASCII.GetBytes(sendStr);

//发送

serverSocket.Send(sendData,sendData.Length,SocketFlags.None);

}

void SocketReceive()

{

SocketConnet();

//不断接收服务器发来的数据

while(true)

{

recvData=new byte[1024];

recvLen=serverSocket.Receive(recvData);

if(recvLen==0)

{

SocketConnet();

continue;

}

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

}

//最后关闭服务器

if(serverSocket!=null)

serverSocket.Close();

print("diconnect");

}

}

TcpTest.cs

using UnityEngine;

using System.Collections;

public class TcpTest:MonoBehaviour

{

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

GameObject cube;

TcpClientHandler tcpClient;

// Use this for initialization

void Start()

{

//初始化网络连接

//tcpClient=new TcpClientHandler(); //因为tcp的类继承了monobehaviour所以不能用new,或者去掉对monobehaviour继承就可以用new

tcpClient=gameObject.AddComponent();

tcpClient.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),tcpClient.GetRecvStr());

if(GUI.Button(new Rect(10,50,60,20),"send"))

tcpClient.SocketSend(editString);

}

// Update is called once per frame

void Update()

{

if(tcpClient.GetRecvStr()!=null)

{

switch(tcpClient.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()

{

//退出时关闭连接

tcpClient.SocketQuit();

}

}

测试

程序实现服务端和客户端互相收发消息,服务端按钮可以控制客户端里面的cube旋转。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值