前言: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.接受服务器发送来的信息(我没做,参照服务器的接受);
小结:答题的项目,我可能会一直记录下其中需要的知识。希望对大家有帮助;项目我就不放了,就两个代码;