Unity简单搭建小服务器和客户端-----------客户端部分

分为两个Unity项目

一个是SeverTest01 用于Unity的服务器部分 --------- 关于服务器部分的
一个是SocketTest01 用于Unity的客户端部分

初步学习只有简单的服务器和客户端连接,并且发送消息回复,算是一个学习记录

分为如下几个脚本 (Event脚本是固定的直接拖到Unity中即可)
在这里插入图片描述
依然还是 代码展示部分

using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System;
using UnityEngine;
using UnityEngine.UI;
public class Client : MonoBehaviour {


    public InputField input;
    public Text receiveText;
    TcpSocket tcpClient;

    private void Start()
    {
        //注册监听事件
        receiveText = GameObject.Find("ReceiveText").GetComponent<Text>();
        //回调函数有四个参数
        EventDispatcher.AddEventListener<string>(EventKey.ServerCallBack, UpdateText);
        //连接地址为家庭,类型为组,协议为Tcp
        Socket client = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);

        tcpClient = new TcpSocket(client,1024,false);
    }

    /// <summary>
    /// 一个具有参数的方法
    /// </summary>
    /// <param name="msg"></param>
    private void UpdateText(string msg)
    {
        //receiveText.text = msg;
    }

    private void Update()
    {
        if (tcpClient != null && tcpClient.ClientConnect())
        {
            tcpClient.ClientReceive();
        }
        receiveText.text = DataManager.Instance.Msg;
    }
    /// <summary>
    /// 设置IP地址,10086为端口号
    /// </summary>
    public void OnClickConnectBtn()
    {
        if (!tcpClient.ClientConnect())
        {
            tcpClient.ClientConnect("10.50.6.160", 10086);
        }
    }
    /// <summary>
    /// 注册Btn的点击事件
    /// </summary>
    public void OnClickToSendServer()
    {
        if (tcpClient != null && tcpClient.ClientConnect() && !String.IsNullOrEmpty(input.text))
        {
            tcpClient.ClientSeed(System.Text.Encoding.UTF8.GetBytes(input.text));
            input.text = "";
        }
    }

    /// <summary>
    /// 
    /// </summary>
    private void OnApplicationQuit()
    {
        if (tcpClient != null && tcpClient.ClientConnect())
        {
            tcpClient.ClientClose();
        }
    }
    /// <summary>
    /// 
    /// </summary>
    private void OnDestroy()
    {
        EventDispatcher.RemoveEventListener<string>(EventKey.ServerCallBack, UpdateText);
    }
}

using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System;
/// <summary>
/// 可以供客户端和服务器一块使用
/// </summary>
public class TcpSocket
{

    //当前实例化的socket
    private Socket socket;
    //socket上的数据
    private byte[] data;
    //区别服务器 还是客户端
    private bool isServer;

    public TcpSocket(Socket socket,int dataLength ,bool isServer)
    {
        this.socket = socket;    

        data = new byte[dataLength];

        this.isServer = isServer;
    }

    #region   接受
    public void ClientReceive()
    {
        //data 数据缓存 0:指的是 接受位的偏移量   data.length指的是数据的长度   SocketFlags.None固定格式   new AsyncCallback(ClientEndReceive)需要有返回值的回调函数,返回值是下面的方法
        //public IAsyncResult BeginReceive(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state);
        socket.BeginReceive(data, 0, data.Length, SocketFlags.None, new AsyncCallback(ClientEndReceive), null);
    }

    public void ClientEndReceive(IAsyncResult ar)
    {
        //数据的处理
        int receiveLength = socket.EndReceive(ar);    //将接受到的数据赋值给receiveLength
        //把接受完毕的字节数组转为string类型
        string dataStr = System.Text.Encoding.UTF8.GetString(data, 0, receiveLength);

        if (isServer)  //判断是否接收到了因为开始设定了isServer是布尔值
        {
            Debug.Log("服务器接收到了:"+ dataStr);

            //接受到了这里回复为
            for (int i = 0; i < Server.Instance.clients.Count; i++)
            {
                if (Server.Instance.clients[i].ClientConnect())
                {
                    Server.Instance.clients[i].ClientSeed(System.Text.Encoding.UTF8.GetBytes("服务器接收到了且回复:" + dataStr));
                }
            }
        }
        else
        {
            DataManager.Instance.Msg = dataStr;

            Debug.Log("客户端接收到了:"+dataStr);
        }
    }
    #endregion

    #region 连接
    public void ClientConnect(string ip, int port)
    {
        socket.BeginConnect(new IPEndPoint(IPAddress.Parse(ip),port),new AsyncCallback(ClientEndConnect),null);
    }

    public void ClientEndConnect(IAsyncResult ar)
    {
        if (ar.IsCompleted)
        {
            Debug.Log("连接成功");
        }
        socket.EndConnect(ar);
    }
    #endregion

    #region   发送
    public void ClientSeed(byte[] data)
    {
        socket.BeginSend(data, 0, data.Length, SocketFlags.None, new AsyncCallback(ClientSeedEnd), null);
    }

    public void ClientSeedEnd(IAsyncResult ar)
    {
        socket.EndSend(ar);
    }

    #endregion

    #region  断开
    public bool ClientConnect()
    {
        return socket.Connected;
    }

    public void ClientClose()
    {
        if (socket != null && ClientConnect())
        {
            socket.Close();
        }
    }
    #endregion
}

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

/// <summary>
/// 关于服务器的脚本
/// </summary>
public class Server : MonoBehaviour {

    private static Server instance;

    public static Server Instance
    {
        get
        {
            return instance;
        }
    }

    private void Awake()
    {
        instance = this;

    }

    private Socket server;

    //所有连接的客户端
    public List<TcpSocket> clients;

    private bool isLoopAccept = true;
    private void Start()
    {
        //服务器socket  协议组 固定格式的协议组
        server = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        //绑定端口号
        server.Bind(new IPEndPoint(IPAddress.Any,10086));
        //可以监听的客户端数目
        server.Listen(100);

        //开辟一个线程  用于处理客户端连接请求
        Thread listenThread = new Thread(ReceiveClient);

        //开启线程
        listenThread.Start();

        //后台运行
        listenThread.IsBackground = true;

        clients = new List<TcpSocket>();

    }


    private void ReceiveClient()
    {
        while (isLoopAccept)
        {
            //开始接受客户端连接请求
            server.BeginAccept(AcceptClient,null);
            //每隔一段时间检测有没有连接
            Thread.Sleep(1000);
        }

        Debug.Log("检测客户端连接中...................");
    }

    private void AcceptClient(IAsyncResult ar)
    {
        Socket client = server.EndAccept(ar);

        TcpSocket clientSocket = new TcpSocket(client,1024,true);
        clients.Add(clientSocket);

        Debug.Log("连接成功");
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DataManager  {

    private static DataManager instance;

    public static DataManager Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new DataManager();

            }
            return instance;
        }


    }

    private DataManager()
    {

    }

    private string msg;

    public string Msg
    {
        get
        {
            return msg;
        }

        set
        {
            //表示数值有更新
            if (msg != value)
            {
                msg = value;

                EventDispatcher.TriggerEvent<string>(EventKey.ServerCallBack,msg);
            }
        }
    }
	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		
	}
}

UI部分也是很简单的搭了几个UI
在这里插入图片描述
注意:按钮的注册事件
还有这里在这里插入图片描述


(项目链接:https://pan.baidu.com/s/16bi4JKJOmEqIom8Nnxv62A 提取码:gkr5 )

猜你喜欢

转载自blog.csdn.net/hennysky/article/details/85004997