在做游戏开发,最近正在将前端与后台连接,就写一下笔记记录一下吧!
我用的是Socket与后台进行连接,数据的传输用的是Json格式。也是从零做起的,以前没有与服务器连接的经验,所以也是结合了网上一些资料。首先说一下总体思路吧,这里没有用异步,采用的是新建了线程,来接收数据,并存到队列进行调用解析。
Socket的建立和链接:
using UnityEngine;
using System.Collections.Generic;
using System.Collections;using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class TcpClientHandler:MonoBehaviour
{
Socket serverSocket; //服务器端socket
private string ClientIP = "192.168.1.139";//IP地址,改成自己的
IPAddress ip; //主机ip
IPEndPoint ipEnd;
string recvStr; //接收的字符串
string sendStr; //发送的字符串
byte[] recvData=new byte[1024]; //接收的数据,必须为字节
byte[] sendData=new byte[1024]; //发送的数据,必须为字节
int recvLen = 0; //接收的数据长度
Thread connectThread; //连接线程
private Queue<string> queue = new Queue<string> ();//新建一个队列,用来存储服务器发来的数据
//服务器初始化
public void InitSocket()
{
ip=IPAddress.Parse(ClientIP);
ipEnd=new IPEndPoint(ip,8009); //服务器端口号,自己改
//开启一个线程连接
connectThread=new Thread(new ThreadStart(SocketReceive));
connectThread.Start();
}
//接收服务器消息
void SocketConnet()
{
if(serverSocket!=null)
serverSocket.Close();
//定义套接字类型,必须在子线程中定义
serverSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//连接
serverSocket.Connect(ipEnd);
recvLen=serverSocket.Receive(recvData);
recvStr=Encoding.UTF8.GetString(recvData,0,recvLen);
print(recvStr);
queue.Enqueue (recvStr);
}
public void SocketSend(string sendStr)
{
//清空发送缓存
sendData=new byte[1024];
//数据类型转换
sendData=Encoding.UTF8.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.UTF8.GetString(recvData,0,recvLen);
queue.Enqueue (recvStr);
print(recvStr);
}
}
//返回接收到的字符串
public string GetRecvStr()
{
string returnStr;
//加锁防止字符串被改
lock(this)
{
if (queue.Count > 0) {//队列内有数据时,取出
returnStr = queue.Dequeue ();
return returnStr;
} }
return null;
}
public void SocketQuit()
{
//关闭线程
if(connectThread!=null)
{
connectThread.Interrupt();
connectThread.Abort();
}
//最后关闭服务器
if(serverSocket!=null)
serverSocket.Close();
}
}
然后在另一个脚本启动服务器:
using UnityEngine;
using System.Collections;
using LitJson;
using UnityEngine.SceneManagement;
public class TcpTest:MonoBehaviour
{
public static TcpTest _instance;
TcpClientHandler tcpClient;
JsonData returnDataJson;
void Awake(){
DontDestroyOnLoad (this.gameObject);
}
// Use this for initialization
void Start()
{
//初始化网络连接
//tcpClient=new TcpClientHandler();
tcpClient=gameObject.AddComponent<TcpClientHandler>();
tcpClient.InitSocket();
}
// Update is called once per frame
void Update()
{
returnDataHandle ();
}
//服务器返回消息的处理
void returnDataHandle(){
returnData = tcpClient.GetRecvStr ();
//print (returnData);
if (returnData != null){
returnDataJson = JsonMapper.ToObject (returnData);
switch(returnDataJson["cmd"].ToString()){
//在此处解析Json,如有项目需要,最好在其他脚本编写,此处只为方便
}
}
}
void OnApplicationQuit()
{
//退出时关闭连接
tcpClient.SocketQuit();
print ("Quit");
}
public void closeC(){//此处比较关键,因为在我们调试时,关闭程序Unity并不一定认为你是退出,所以上面代码也许不会执行,导致与服务器一直连接,Unity崩溃
tcpClient.SocketQuit();
print ("closeC");
}
}
最后说一下Json的处理,首先要导入LitJson库,然后在脚本中using LitJson。
发送数据举例:
//注册
public void RegisterEvent(string username, string password){
JsonData registerJson = new JsonData ();
registerJson ["cmd"] = "Login|register";
registerJson ["name"] = "wyq";
registerJson ["tel"] = username;
registerJson ["psd"] = password;
string registrStr = registerJson.ToJson();
tcpClient.SocketSend (registrStr);
}
接收的处理上面代码中已有部分介绍,在获取json数据后,进行解析调用即可。