1. 程式人生 > >u3d下的Tcp和Udp通訊的兩種寫法

u3d下的Tcp和Udp通訊的兩種寫法

1、使用Socket的Tcp

    服務端:

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

using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;


public class ScocketServer : MonoBehaviour {

    private Thread _StartServer;

    byte[] byte_receive;
    Socket RecieveSocket;
    IPEndPoint iep;
    EndPoint ep;
    // Use this for initialization
    void Start () {

        //Socket Tcp
        byte_receive = new byte[100];
        iep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1001);
        RecieveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        RecieveSocket.Bind(iep);
        RecieveSocket.Listen(10);

        _StartServer = new Thread(StartServer);
        _StartServer.Start();

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

    }

    void StartServer()
    {
        Debug.Log("服務端:等人...");
        Socket tempSocket = RecieveSocket.Accept();//阻斷
        Debug.Log("服務端:有人來了");
        while (true)
        {
            int datalength = tempSocket.Receive(byte_receive);
            if (datalength != 0)
            {
                string msg = Encoding.Unicode.GetString(byte_receive);
                Debug.Log("服務端:我收到訊息:" + msg);
            }
        }
    }

    private void OnApplicationQuit()
    {
        if (_StartServer != null)//關閉執行緒
        {
            _StartServer.Interrupt();
            _StartServer.Abort();
        }
        //最後關閉socket
        if (RecieveSocket != null)
            RecieveSocket.Close();
    }
}

    客戶端:

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

using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.Threading;

public class ScocketClient : MonoBehaviour {

    private Thread ClientThread;
    int MsgIndex;
    Socket ClientSocket;
    IPEndPoint ep;
    string msg;
    byte[] byteSendingArray;
    // Use this for initialization
    void Start () {
        ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1001);
         byteSendingArray = new byte[100];
        MsgIndex = 0;
    }
	
	// Update is called once per frame
	void Update () {
		if(Input.GetKeyDown(KeyCode.Alpha1))
            {
                SendMsg();
            }
	}

    private void SendMsg()
    {
        try
        {
            if(ClientSocket == null)
            {
                ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                ClientSocket.Connect(IPAddress.Parse("127.0.0.1"), 1001);
                ClientSocket.Receive(byteSendingArray);
                Debug.Log(Encoding.Unicode.GetString(byteSendingArray));
            }

            msg = "客戶端:啊~~~" + MsgIndex + "環";

            byteSendingArray = Encoding.Unicode.GetBytes(msg);
            ClientSocket.Send(byteSendingArray);
        }
        catch (Exception ex)
        {
            Debug.Log(ex.Message);
        }
        MsgIndex++;
    }
}

2、使用Socket的Udp

    服務端:

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

using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;


public class ScocketServer : MonoBehaviour {

    private Thread _StartServer;

    byte[] byte_receive;
    Socket RecieveSocket;
    IPEndPoint iep;
    EndPoint ep;
    // Use this for initialization
    void Start () {

        //Socket Udp
        byte_receive = new byte[100];
        iep = new IPEndPoint(IPAddress.Any, 1001);
        RecieveSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
        RecieveSocket.Bind(iep);
        ep = (EndPoint)iep;

        _StartServer = new Thread(StartServer);
        _StartServer.Start();

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

    }

    void StartServer()
    {
        //Socket Udp
        while (true)
        {
            int intReceiveLength = RecieveSocket.ReceiveFrom(byte_receive, ref ep);
            string strReceiveStr = Encoding.Unicode.GetString(byte_receive, 0, intReceiveLength);
            Debug.Log("收到訊息:  " + strReceiveStr);
        }
    }

    private void OnApplicationQuit()
    {
        if (_StartServer != null)
        {
            _StartServer.Interrupt();
            _StartServer.Abort();
        }
        //最後關閉socket
        if (RecieveSocket != null)
            RecieveSocket.Close();
    }
}

    客戶端:

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

using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.Threading;

public class ScocketClient : MonoBehaviour {

    TcpClient MyClient;
    private Thread ClientThread;
    int MsgIndex;
    Socket ClientSocket;
    IPEndPoint ep;
    string msg;
    byte[] byteSendingArray;
    // Use this for initialization
    void Start () {
        ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1001);
         byteSendingArray = new byte[100];MsgIndex = 0;
        ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    }
	
	// Update is called once per frame
	void Update () {
		if(Input.GetKeyDown(KeyCode.Alpha1))
            {
                SendMsg();
            }
	}

    private void SendMsg()
    {
        try
        {
            //Socket Udp
            msg = "客戶端:啊~~~" + MsgIndex + "環";
            byteSendingArray = Encoding.Unicode.GetBytes(msg);
            ClientSocket.SendTo(byteSendingArray,ep);
        }
        catch (Exception ex)
        {
            Debug.Log(ex.Message);
        }
        MsgIndex++;
    }
}

3、不使用Socket的Tcp

    服務端:

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

using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;


public class ScocketServer : MonoBehaviour {

    private Thread _StartServer;

    byte[] byte_receive;
    Socket RecieveSocket;
    IPEndPoint iep;
    EndPoint ep;
    // Use this for initialization
    void Start () {
        _StartServer = new Thread(StartServer);
        _StartServer.Start();

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

    }

    void StartServer()
    {
        //tcp-----------------------------
        const int MyBuffSize = 1024;
        IPAddress ServerIP = IPAddress.Parse("127.0.0.1");

        TcpListener myListener = new TcpListener(ServerIP, 10001);
        myListener.Start();
        Debug.Log("伺服器監聽,啟動!!");

        TcpClient remoteClient = myListener.AcceptTcpClient();  //阻塞
        Debug.Log("有客到!");
        NetworkStream ClientStream = remoteClient.GetStream();

        byte[] buffer = new byte[MyBuffSize];
        do
        {
            try
            {
                int byteRead = ClientStream.Read(buffer, 0, MyBuffSize);
                if (byteRead == 0)
                {
                    Debug.Log("沒東西啊!!");
                    continue;
                }

                string msg = Encoding.Unicode.GetString(buffer, 0, byteRead);
                Debug.Log("接收資料:" + msg);
            }
            catch (Exception ex)
            {
                Debug.Log("異常:" + ex.Message);
                break;
            }
        }
        while (true);

    }

    private void OnApplicationQuit()
    {
        if (_StartServer != null)
        {
            _StartServer.Interrupt();
            _StartServer.Abort();
        }
    }
}

    客戶端:

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

using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.Threading;

public class ScocketClient : MonoBehaviour {

    TcpClient MyClient;
    private Thread ClientThread;
    int MsgIndex;
    Socket ClientSocket;
    IPEndPoint ep;
    string msg;
    byte[] byteSendingArray;
    // Use this for initialization
    void Start () {
        //tcp-------------------------------
        MsgIndex = 0;
        MyClient = new TcpClient();
        try
        {
            MyClient.Connect(IPAddress.Parse("127.0.0.1"), 10001);
        }
        catch (Exception ex)
        {
            Debug.Log("客戶端連線異常:" + ex.Message);
        }
    }
	
	// Update is called once per frame
	void Update () {
		if(Input.GetKeyDown(KeyCode.Alpha1))
            {
                SendMsg();
            }
	}

    private void SendMsg()
    {
        //tcp---------------------------------
        try
        {
            string msg = "我是訊息  " + MsgIndex;
            NetworkStream streamToServer = MyClient.GetStream();//獲得客戶端的流
            byte[] buffer = Encoding.Unicode.GetBytes(msg);//將字串轉化為二進位制
            streamToServer.Write(buffer, 0, buffer.Length);//將轉換好的二進位制資料寫入流中併發送
            Debug.Log("發出訊息:" + msg);
        }
        catch (Exception ex)
        {
            Debug.Log("異常:" + ex.Message);
        }

        MsgIndex++;
    }
}

4、不使用Socket的Udp

    服務端:

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

using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;


public class ScocketServer : MonoBehaviour {

    private Thread _StartServer;

    UdpClient MyUdpClient;
    // Use this for initialization
    void Start () {

        _StartServer = new Thread(StartServer);
        _StartServer.Start();

    }
    void StartServer()
    {
        //udp-----------------------------


        IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 1234);
            MyUdpClient = new UdpClient(10001);

        while (true)
        {
                byte[] data = MyUdpClient.Receive(ref anyIP);
                string msg = Encoding.Unicode.GetString(data);
                Debug.Log("收到訊息:" + msg);
        }
    }

    private void OnApplicationQuit()
    {
        if (MyUdpClient != null)
            MyUdpClient.Close();
        if (_StartServer != null)
        {
            _StartServer.Interrupt();
            _StartServer.Abort();
        }
    }
}

客戶端:

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

using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.Threading;

public class ScocketClient : MonoBehaviour {

    UdpClient MyUdpClient;
    int MsgIndex;
    // Use this for initialization
    void Start () {
        ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 10001);
        MyUdpClient = new UdpClient();
        MyUdpClient.Connect(ep);
    }

    // Update is called once per frame
    void Update () {
		if(Input.GetKeyDown(KeyCode.Alpha1))
            {
                SendMsg();
            }
	}

    private void SendMsg()
    {
        //udp---------------------------------
        string msg = "我是訊息  " + MsgIndex;
        byte[] buffer = Encoding.Unicode.GetBytes(msg);
        Debug.Log("發出訊息:" + msg);
        MyUdpClient.Send(buffer, buffer.Length);

        MsgIndex++;
    }

    private void OnApplicationQuit()
    {
        if (MyUdpClient != null)
            MyUdpClient.Close();
    }
}

        其實說服務端客戶端還不如說接收端傳送端,Tcp和Udp都是傳輸層協議,是一套約定好的傳輸法則,不同的是,Tcp要建立連線才能傳輸,Udp則不需要。用屁股也想得到,需要建立連線的,肯定要安全一點,也肯定要慢一些,有優點自然有缺點嘛。(是不是有點像Durex,笑)

        需要注意的點:

        1、埠對應。

        2、阻斷函式(執行緒)

        3、記得釋放(貓兒拉屎貓兒埋)