您的位置:首页 > 理论基础 > 计算机网络

Unity3D笔记——TCP简单服务器和客户端的连接和异步接受

2018-02-08 17:34 603 查看

前言:Unity3D笔记是我平时做一些好玩的测试和研究,记录的笔记。会比较详细也可能随口一提就过了。 所以大家见谅了,内容一般都会是原创的(非原创我会注明转载)。由于很多内容其他的朋友也肯定研究发表过,大家请指出错误。

公司需要做个简单的答题游戏,然后是局域网的四台固定设备,互相组队开始比赛答题。然后肯定需要用到网络啦,想啦下,需要有房间的思想。为了节约成本,就让其中先开局当服务器(房间),再用UDP广播出去地址,其他机器会知道服务器地址 之后在接入,开始游戏。 最后协议打算用TCP的,今天就打了稿子实现简单的功能;(感谢《unity3D网络游戏实战》对我帮助很大)。

直接上代码:服务器的

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using System.Net;
using System;

public class GameServer : MonoBehaviour {

private Socket listenSocket;

//客户端的池
private List<Unit> conns = new List<Unit>();

void Start () {

}

/// <summary>
/// 开启服务器
/// </summary>
public void StartServer(string host,int port)
{
//实例化套接字
listenSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

//定义端口和地址
IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse(host),port);

//将套接字和端口绑定
listenSocket.Bind(iPEndPoint);

//定义不能超过4个客户端接入
listenSocket.Listen(4);

//开始接入
listenSocket.BeginAccept(AcceptCb,null);

Debug.Log("GameServer is Open");
}

/// <summary>
/// 关闭服务器
/// </summary>
public void CloseServer()
{

foreach (var item in conns)
{
item.socket.Close();
}

listenSocket.Close();
}

/// <summary>
/// AcceptCb的回调
/// </summary>
/// <param name="ar"></param>
private void AcceptCb(IAsyncResult ar)
{
try
{
//获取接入的socket
Socket socket = listenSocket.EndAccept(ar);

//实例化一个conn对象
Unit conn = new Unit(socket);

//放入客户端池子中
conns.Add(conn);

//开始异步接受,并把conn对象传过去
conn.socket.BeginReceive(conn.readBuff,0,conn.readBuffCount,SocketFlags.None,ReceiveCb,conn);

//继续监听接入
listenSocket.BeginAccept(AcceptCb, null);
}
catch (Exception e)
{
Debug.LogError(e.Message);
throw;
}
}

/// <summary>
/// 异步接受的回调
/// </summary>
/// <param name="ar"></param>
private void ReceiveCb(IAsyncResult ar)
{
//获取该异步接受的客户端套接字
Unit conn = (Unit)ar.AsyncState;

try
{
//接受的到的数据长度
int count = conn.socket.EndReceive(ar);

//数据处理
string str = System.Text.Encoding.UTF8.GetString(conn.readBuff,0,count);

Debug.Log(str);

//开始异步接受,并把conn对象传过去
conn.socket.BeginReceive(conn.readBuff, 0, conn.readBuffCount, SocketFlags.None, ReceiveCb, conn);
}
catch (Exception e)
{
Debug.LogError(e.Message);
throw;
}
}
}

/// <summary>
/// 客户端对象
/// </summary>
public class Unit {

/// <summary>
/// 用于存储客户端的套接字
/// </summary>
public Socket socket;

/// <summary>
/// 接受数据的缓存空间
/// </summary>
public byte[] readBuff = new byte[1024];

public int readBuffCount = 1024;

/// <summary>
/// 构造函数
/// </summary>
/// <param name="socket"></param>
public Unit(Socket socket)
{
this.socket = socket;
}

}


说明:服务器的建立有这么几个顺序:1.建立套接字(socket);2.bind本地的地址和端口;3.开始监听客户端的接入(这边需要用异步的,不然会卡死);4.如果客户端接入了,获取其socket 开始异步接受信息。并将客户端信息保存在自己池子里。5.可以向客户端发送信息(我没做,代码和客户端本地发信息一样的);

客户端的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using System.Net;
using System;

public class GameClient  {

//服务器端的地址
public string serverHost;

//服务器端的端口
public int serverPort;

//套接字
public Socket socket;

public byte[] readBuff = new byte[1024];

private int readBuffSize = 1024;

/// <summary>
/// 向服务器请求接入
/// </summary>
/// <param name="host"></param>
/// <param name="port"></param>
public void Connetion(string host,int port)
{
//实例化套接字
socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

socket.Connect(host, port);

//开始异步接受数据
socket.BeginReceive(readBuff,0,readBuffSize,SocketFlags.None,ReceiveCb,null);
}

/// <summary>
/// 异步接受的回调
/// </summary>
/// <param name="ar"></param>
private void ReceiveCb(IAsyncResult ar)
{
//收到数据的长度
int count = socket.EndReceive(ar);

try
{
//处理收到的数据
string str = System.Text.Encoding.UTF8.GetString(readBuff,0,count);

//继续开始异步接受数据
socket.BeginReceive(readBuff, 0, readBuffSize, SocketFlags.None, ReceiveCb, null);
}
catch (Exception e)
{
Debug.LogError(e.Message);
throw;
}

}

/// <summary>
/// 发送数据
/// </summary>
/// <param name="data"></param>
public void Send(string data)
{
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data);

try
{
socket.Send(bytes);
}
catch (Exception e)
{
Debug.LogError(e.Message);
throw;
}
}
}


说明:客户端就简单多了,照例说下顺序:1.建立套接字;2.向服务器申请接入(这里需要知道目标服务器的地址和端口了,局域网需要广播接受到,大家可以看我之前的文章有UDP的广播);3.向服务器发送信息;4.接受服务器发送来的信息(我没做,参照服务器的接受);

小结:答题的项目,我可能会一直记录下其中需要的知识。希望对大家有帮助;项目我就不放了,就两个代码;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  unity tcp
相关文章推荐