在Unity中客户端与服务器端的2种通信方式(Socker)

15:17 2019/5/10
//第一种
using UnityEngine;
using System.Collections;
//引入库
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine.UI;

public class UdpClient : MonoBehaviour
{
    string editString = "hello wolrd"; //编辑框文字

    //以下默认都是私有的成员
    Socket socket; //目标socket
    EndPoint serverEnd; //服务端
    IPEndPoint ipEnd; //服务端端口
    string recvStr; //接收的字符串
    string sendStr; //发送的字符串
    byte[] recvData = new byte[1024]; //接收的数据,必须为字节
    byte[] sendData = new byte[1024]; //发送的数据,必须为字节
    int recvLen; //接收的数据长度
    Thread connectThread; //连接线程

    //初始化
    void InitSocket()
    {
        //定义连接的服务器ip和端口,可以是本机ip,局域网,互联网
        ipEnd = new IPEndPoint(IPAddress.Parse("192.168.1.133"), 7000);
        //定义套接字类型,在主线程中定义
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        //定义服务端
        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
        serverEnd = (EndPoint)sender;
        print("waiting for sending UDP dgram");

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

        //开启一个线程连接,必须的,否则主线程卡死
        connectThread = new Thread(new ThreadStart(SocketReceive));
        connectThread.Start();
    }

    public void OnBtnClick(string command)
    {
        Debug.Log("send command: " + command);
        this.SocketSend(command);
    }

    void SocketSend(string sendStr)
    {
        //清空发送缓存
        sendData = new byte[1024];
        //数据类型转换
        sendData = Encoding.ASCII.GetBytes(sendStr);
        //发送给指定服务端
        socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);
    }

    //服务器接收
    void SocketReceive()
    {
        //进入接收循环
        while (true)
        {
            //对data清零
            recvData = new byte[1024];
            //获取客户端,获取服务端端数据,用引用给服务端赋值,实际上服务端已经定义好并不需要赋值
            recvLen = socket.ReceiveFrom(recvData, ref serverEnd);
            print("message from: " + serverEnd.ToString()); //打印服务端信息
            //输出接收到的数据
            recvStr = Encoding.ASCII.GetString(recvData, 0, recvLen);
            print(recvStr);
        }
    }

    //连接关闭
    void SocketQuit()
    {
        //关闭线程
        if (connectThread != null)
        {
            connectThread.Interrupt();
            connectThread.Abort();
        }
        //最后关闭socket
        if (socket != null)
            socket.Close();
    }

    // Use this for initialization
    void Start()
    {
        InitSocket(); //在这里初始化
    }

    void OnGUI()
    {
        //editString = GUI.TextField(new Rect(10, 10, 100, 20), editString);
        //if (GUI.Button(new Rect(10, 30, 60, 20), "send"))
        //    SocketSend(editString);
    }

    // Update is called once per frame
    void Update()
    {

    }

    void OnApplicationQuit()
    {
        SocketQuit();
    }
}




//第二种
#region UDP客户端类
using UnityEngine;
using System.Collections;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine.UI;

public class UDPClient : MonoBehaviour
{
    public string recvStr;
    服务端的IP地址
    private string UDPClientIP;
    string str = "客户端01发送消息";
    //目标socket
    Socket socket;
    //服务端
    EndPoint serverEnd;
    //服务端端口
    //IPEndPoint是ip和端口对的组合
    IPEndPoint ipEnd;

    //接收的数据,必须为字节 
    byte[] recvData = new byte[1024];
    //发送的数据,必须为字节
    byte[] sendData = new byte[1024];
    //接收的数据长度 
    int recvLen = 0;
    //连接线程
    Thread connectThread;

    private bool isStarted;
    public Text Number;

    void Start()
    {
        UDPClientIP = "192.168.1.45";//服务端的IP.自己更改
        UDPClientIP = UDPClientIP.Trim();
        InitSocket();//初始化


    }

   

    public void StartGame()
    {
        Debug.Log("start game");
        this.isStarted = true;
        InvokeRepeating("TimerEvent", 0.5f, 0.1f);
    }

    public void GameOver()
    {
        CancelInvoke("TimerEvent");
        this.isStarted = false;
        Debug.Log("game over");
    }

    void TimerEvent()
    {
        if(!this.isStarted)
        {
            return;
        }

        byte[] cmd = new byte[] { 0x00, 0x5A, 0x56, 0x00, 0x07, 0x00, 0x00, 0x00, 0xB7 };
        SocketSend(cmd);
    }

    void InitSocket()
    {
        //定义连接的服务器ip和端口,可以是本机ip,局域网,互联网 
        //IPAddress 类包含计算机在 IP 网络上的地址
        //IPAddress.Parse将 IP 地址字符串转换为 IPAddress 实例
        ipEnd = new IPEndPoint(IPAddress.Parse(UDPClientIP), 4002);
        //初始化一个Scoket实习,采用UDP传输
        //定义套接字类型,在主线程中定义 
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        //定义服务端 
        IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
        serverEnd = (EndPoint)sender;
        print("等待连接");
        SocketSend(str);
        print("连接");
        


        Loom.RunAsync(
            () =>
            {
                //开启一个线程连接
                connectThread = new Thread(new ThreadStart(SocketReceive));
                connectThread.Start();
            }
            );
    }
 void IncScore(int score)
    {
        int temp = Convert.ToInt32(Number.text);
        temp += score;
        //Number.text = temp + "";

        // 用Loom的方法在Unity主线程中调用Text组件
        Loom.QueueOnMainThread((param) =>
        {
            //mText.text = "Hello Loom!";
            Number.text = temp + "";
        }, null);
    }
    //发送数据
    void SocketSend(byte[] sendStr)
    {
        //清空
        sendData = new byte[1024];
        //数据转换
        sendData = sendStr;
        //发送给指定服务端
        socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);
    }

    //发送字符串
    void SocketSend(string sendStr)
    {
        //清空
        sendData = new byte[1024];
        //数据转换
        sendData = Encoding.UTF8.GetBytes(sendStr);
        //发送给指定服务端
        socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);
    }


    string ToHexString(byte[] bytes) // 0xae00cf => "AE00CF "
    {
        string hexString = string.Empty;

        if (bytes != null)

        {

            StringBuilder strB = new StringBuilder();

            for (int i = 0; i < bytes.Length; i++)

            {

                strB.Append(bytes[i].ToString("X2"));

            }

            hexString = strB.ToString();

        }
        return hexString;

    }

    //接收服务器信息
    void SocketReceive()
    {
        //进入接收循环 
        while (true)
        {
            //对data清零 
            recvData = new byte[10];
            try
            {
                //获取服务端端数据
                recvLen = socket.ReceiveFrom(recvData, ref serverEnd);
                //print("信息来自: " + serverEnd.ToString());
                if (recvLen > 0)
                {
                    //recvStr = ToHexString(recvData);//Encoding.UTF8.GetString(recvData, 0, recvLen);
                    ExtractResult(recvData);
                }

                //print(recvStr);
            }
            catch (Exception e)
            {
                sleep();
            }

            
        }
    }

    public System.Collections.IEnumerator sleep()
    {
        yield return new WaitForSeconds(0.5f);
    }

    void ExtractResult(byte[] result)
    {
        if(result[7]==0xFF)
        {
            return;
        }

        /*
         中间:7F
         左边::BF
         右边:DF
        */

        if(result[7] == 0xDF)
        {
            IncScore(20);
        }else if(result[7] == 0x7F)
        {
            IncScore(40);
        }
        else if (result[7] == 0xBF)
        {
            IncScore(40);
        }
    }





    //连接关闭
    void SocketQuit()
    {
        //关闭线程
        if (connectThread != null)
        {
            connectThread.Interrupt();
            connectThread.Abort();
        }
        //最后关闭socket
        if (socket != null)
            socket.Close();
    }
    void OnApplicationQuit()
    {
        SocketQuit();
    }

    void Update()
    {

    }

}

  

转载于:https://www.cnblogs.com/clhxxlcj/p/10916768.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值