Unity in Socket Programming (TCP protocol)

Service-Terminal:

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

public class TCPServer : MonoBehaviour {

    public string ipAddress = "127.0.0.1";
    public int port = 10000;

    private byte[] data = new byte[1024];
    private Socket serverSocket;        //服务器Socket
    private Socket client;              //客户端socket
    private Thread myThread;            //启动监听线程
    private Thread receiveThread;       //接收数据线程

    private List<Socket> clientSocketList = new List<Socket>();     //用于存储客户端
	void Start () {
        InitSocket();
	}

    void InitSocket()
    {
        try
        {
            //在主线程中定义套接字的类型
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint iPPoint = new IPEndPoint(IPAddress.Parse(ipAddress), port);      //定义监听的IP和端口

            serverSocket.Bind(iPPoint);     //绑定IP和端口
            serverSocket.Listen(10);        //开启监听,最大连接数为10个连接

            Debug.Log("Server Running...");
            myThread = new Thread(ListenClientConnect);     //开启一个线程连接,防止主线程卡死
            myThread.Start();           //开启线程

        }
        catch (System.Exception ex)
        {
            Debug.Log(ex.Message);
        }
    }

    //监听客户端连接
    void ListenClientConnect()
    {
        while (true)
        {
            client = serverSocket.Accept();     //接收连接后,创建一个客户端
            clientSocketList.Add(client);       //加入到客户端链表

            Debug.Log("客户端:" + client.RemoteEndPoint + "连接到服务器!");
            AllSendMs("From Server : " + client.RemoteEndPoint + "客户端已连接到服务器!");

            receiveThread = new Thread(ReceiveMsg);
            receiveThread.Start(client);
        }
    }

    //接收消息
    void ReceiveMsg(object clientSocket)
    {
        client = clientSocket as Socket;
        while (true)
        {
            try
            {
                int length = 0;
                length = client.Receive(data);

                //Poll():用于检查Socket的状态 参数一:等待响应的时间(以微秒为单位)
                //参数二:SelectRead : 读状态模式,SelectWrite : 写状态模式  SelectError : 错误状态
                if (length == 0 || client.Poll(1000,SelectMode.SelectRead))
                {
                    string s = "客户端 : " + client.RemoteEndPoint + "断开连接!";
                    Debug.Log(s);
                    AllSendMs(s);
                    clientSocketList.Remove(client);
                    break;
                }
                string str = Encoding.UTF8.GetString(data, 0, data.Length);     //以UTF8编码方式转换数组为字符串

                AllSendMs(str);
            }
            catch (System.Exception)
            {
                throw;
            }
        }
    }

    //发送全部消息
    void AllSendMs(string ms)
    {
        for (int i = 0; i < clientSocketList.Count; i++)
        {
            clientSocketList[i].Send(Encoding.UTF8.GetBytes(ms));
        }
    }

    /// <summary>
    /// 销毁时将开启的线程和Socket关闭
    /// </summary>
    private void OnDestroy()
    {
        if (myThread != null || receiveThread != null)
        {
            myThread.Interrupt();   //中断线程
            myThread.Abort();       //立即终止线程

            receiveThread.Interrupt();
            receiveThread.Abort();
        }

        if (serverSocket != null)
        {
            for (int i = 0; i < clientSocketList.Count; i++)
            {
                clientSocketList[i].Close();
            }

            //shutdown是一种优雅的单方向或者双方向关闭socket的方法。而close则立即双向强制关闭socket并释放相关资源
            //如果有多线程共享一个socket,shutdown影响所有进程,而close只影响本进程
            serverSocket.Shutdown(SocketShutdown.Both);
            serverSocket.Close();
        }

    }
}

Client:

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

public class TCPClient : MonoBehaviour
{

    public string ipAdress = "127.0.0.1";
    public int port = 10000;

    private byte[] data = new byte[1024];
    private Socket clientSocket;
    private Thread receiveT;

    void Start()
    {
        OnConnectedToServer();
    }

    //连接服务器
    private void OnConnectedToServer()
    {
        try
        {
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            clientSocket.Connect(IPAddress.Parse(ipAdress), port);      //用于连接服务器
            Debug.Log("连接服务器成功");

            receiveT = new Thread(ReceiveMsg);
            receiveT.Start();
        }
        catch (System.Exception ex)
        {
            Debug.Log("连接服务器失败!");
            Debug.Log(ex.Message);
        }
    }

    //接收数据
    private void ReceiveMsg()
    {
        while (true)
        {
            if (clientSocket.Connected == false)
            {
                Debug.Log("与服务器断开连接");
                break;
            }
            int length = 0;
            length = clientSocket.Receive(data);

            string str = Encoding.UTF8.GetString(data, 0, data.Length);
            Debug.Log(str);
        }
    }

    void SendMes(string ms)
    {
        byte[] data = new byte[1024];
        data = Encoding.UTF8.GetBytes(ms);
        clientSocket.Send(data);
    }

    private void OnDestroy()
    {
        if (clientSocket != null)
        {
            clientSocket.Shutdown(SocketShutdown.Both);
            clientSocket.Close();
        }

        if (receiveT != null)
        {
            receiveT.Interrupt();
            receiveT.Abort();
        }
    }
}

Reprinted: https://blog.csdn.net/sinat_34791632/article/details/79722440

Guess you like

Origin blog.csdn.net/qq_38721111/article/details/88851456