UDP客户端

2018-12-29  本文已影响0人  咆哮的小老虎

UDPClient

using UnityEngine;

using System.Collections;

using System;

using System.IO;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Threading;

public class UDPClient : MonoBehaviour

{

    public static UDPClient instance;

    //服务端的IP

    string UDPClientIP;

    //目标socket

    Socket socket;

    //服务端

    EndPoint serverEnd;

    //服务端端口

    IPEndPoint ipEnd;

    //接收的字符串

    string recvStr;

    //发送的字符串

    string sendStr;

    //接收的数据,必须为字节

    byte[] recvData = new byte[1024];

    //发送的数据,必须为字节

    byte[] sendData = new byte[1024];

    //接收的数据长度

    int recvLen = 0;

    //连接线程

    Thread connectThread;

    bool isClientActive = false;

    //连接服务器时发送的vector3类型

    Vector3 startVec = Vector3.zero;

    bool isStartHeart = false;

    public delegate void UDPClientDelegate(string str);

    public event UDPClientDelegate UDPClientEvent;

    [HideInInspector]

    public bool isStartReceive = false;

    private void Awake()

    {

        instance = this;

    }

    void Start()

    {

        UDPClientIP = "192.168.5.209";//服务端的IP.自己更改

        UDPClientIP = UDPClientIP.Trim();

        isClientActive = true;

        InitSocket(); //在这里初始化

    }

    private void Update()

    {

        if (isStartHeart)

        {

            HeartSend();

        }

        //检测心跳与心跳反馈的间隔时间,

        timerInterval += Time.deltaTime;

        if (isStartCheckIntervalTime)

        {

            if (timerInterval>3f)

            {

                print("连接异常");

                isStartCheckIntervalTime = false;

            }

        }

        if (isStartReceive)

        {

            if (UDPClientEvent != null)

            {

                UDPClientEvent(recvStr);

            }

        }

    }

    //初始化

    void InitSocket()

    {

        //定义连接的服务器ip和端口,可以是本机ip,局域网,互联网

        ipEnd = new IPEndPoint(IPAddress.Parse(UDPClientIP),8888);

        //定义套接字类型,在主线程中定义

        socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

        //socket.Bind(ipEnd);

        //定义服务端

        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);

        serverEnd = (EndPoint)sender;

        print("local:等待连接");

        //建立初始连接,这句非常重要,第一次连接初始化了serverEnd后面才能收到消息

        SocketSend("hello");

        //SocketSendVector(startVec);

        // print("local:连接");

        isStartHeart = true;

        //开始心跳监听

        //客户端发送心跳消息后,计时器开始计时,判断3秒内是否能收到服务端的反馈

        HeartSend();

        //开启一个线程连接,必须的,否则主线程卡死

        connectThread = new Thread(new ThreadStart(SocketReceive));

        connectThread.Start();

    }

    //发送字符串

    void SocketSend(string sendStr)

    {

        //清空发送缓存

        sendData = new byte[1024];

        //数据类型转换

        sendData = Encoding.UTF8.GetBytes(sendStr);

        //发送给指定服务端

        socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);

    }

    /// <summary>

    /// 发送vector3

    /// </summary>

    /// <param name="sendVec"></param>

  public  void SocketSendVector(Vector3 sendVec)

    {

        string sendstr= sendVec.ToString();

        //清空发送缓存

        sendData = new byte[1024];

        //数据类型转换

        sendData = Encoding.UTF8.GetBytes(sendstr);

        //发送给指定服务端

        socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);

    }

    //发送消息频率

    float timerRate=0;

    //接收服务端心跳反馈的时间间隔

    float timerInterval = 0f;

    byte[] heartSendData = new byte[1024];

    /// <summary>

    /// 心跳

    /// </summary>

    void HeartSend() {

        //  while (true) {

        timerRate += Time.deltaTime;

            if (timerRate >2f)

            {

                try

                {

                    //清空发送缓存

                    heartSendData = new byte[1024];

                    //数据类型转换

                    heartSendData = Encoding.UTF8.GetBytes("alive");

                    //发送给指定服务端

                    socket.SendTo(heartSendData, heartSendData.Length, SocketFlags.None, ipEnd);

                    print("心跳");

                isStartCheckIntervalTime = true;

            }

                catch (Exception e)

                {

                    print(e.Message);

                }

                timerRate = 0f;

          //  }

        }

    }

    //客户端接收服务器消息

    void SocketReceive()

    {

        //进入接收循环

        while (isClientActive)

        {

            //对data清零

            recvData = new byte[1024];

            try

            {

                //获取服务端端数据

                recvLen = socket.ReceiveFrom(recvData, ref serverEnd);

                if (isClientActive == false) {

                    break;

                }

            }

            catch (Exception e)

            {

                print(e.Message);

            }

            //打印服务端信息

            //print("local:message from--" + serverEnd.ToString());

            //输出接收到的数据

            if (recvLen > 0)

            {

                //接收到的信息

                recvStr = Encoding.UTF8.GetString(recvData, 0, recvLen);

            }

            //  print("server:" + recvStr);

            //if (UDPClientEvent != null)

            //{

            //    UDPClientEvent(recvStr);

            //}

            isStartReceive = true;

            //心跳回馈

            ServerKeepConnect(recvStr);

        }

    }

    //发送心跳包后开始检测计时,固定时间内没有收到反馈则为连接异常

    bool isStartCheckIntervalTime = false;

    void ServerKeepConnect(string str) {

        string receiveMsg = str;

        // 当服务端收到客户端发送的alive消息时,

              // timerInterval += 0.02f;

    //  if (timerInterval > 3f)

      //  {

          // print("连接异常");

      //  }

      //  else

      //  {

            if (receiveMsg == "keeping")

            {

                print("连接正常");

                timerInterval = 0;

                receiveMsg = "";

            isStartCheckIntervalTime = false;

            }

      // }

    }

    //连接关闭

    void SocketQuit()

    {

        //关闭线程

      // if (connectThread != null)

        //{

          // connectThread.Interrupt();

          // connectThread.Abort();

      // }

        //最后关闭socket

        if (socket != null)

            socket.Close();

    }

    void OnApplicationQuit()

    {

        isClientActive = false;

          SocketQuit();

        Thread.Sleep(25);

    }

    public void ButtonSend(string a)

    {

        SocketSend(a);

    }

    public void ButtonDoSomething()

    {

        ButtonSend("DoSomething");

    }

}

上一篇 下一篇

猜你喜欢

热点阅读