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

前言: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.接受服务器发送来的信息(我没做,参照服务器的接受);


小结:答题的项目,我可能会一直记录下其中需要的知识。希望对大家有帮助;项目我就不放了,就两个代码;

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值