- 客户端 1.Unity里编写客户端的代码 2.在Unity3d中创建脚本”SocketClient”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 using System;using System.Collections;using System.Collections.Generic;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;using UnityEngine;public delegate void DelegateMsg (string Msg ) ;public class SocketClient { private Socket clientSocket; public string ServerIP; public int ServerPort; public DelegateMsg delegateMsg; private Thread acceptMsgThread; private int MAX_SEND_FILE_LENGTH = 4096 ; public SocketClient (string _serverIP, int _serverPort ) { ServerIP = _serverIP; ServerPort = _serverPort; } public bool ConnectServer () { if (ServerIP == null || ServerPort == 0 ) { return false ; } try { clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress serverIp = IPAddress.Parse(ServerIP); IPEndPoint endPoint = new IPEndPoint(serverIp, ServerPort); clientSocket.Connect(endPoint); acceptMsgThread = new Thread(AcceptMsgs); acceptMsgThread.IsBackground = true ; acceptMsgThread.Start(); return true ; } catch (Exception e) { return false ; } } private void AcceptMsgs () { try { while (true ) { byte [] buffer = new byte [MAX_SEND_FILE_LENGTH]; int dataLength = clientSocket.Receive(buffer); if (dataLength == 0 ) { break ; } string strMsg = Encoding.UTF8.GetString(buffer, 0 , dataLength); Debug.Log("客户端接受到消息:" + strMsg); Loom.QueueOnMainThread((param) => { delegateMsg(strMsg); }, null ); } } catch (Exception e) { } } public bool SubmitMsgToServer (string msg ) { if (clientSocket == null || !clientSocket.Connected) { return false ; } try { byte [] buffer = Encoding.UTF8.GetBytes(msg); clientSocket.Send(buffer); return true ; } catch (Exception e) { Debug.Log("客户端发送数据发生异常:" + e.ToString()); return false ; } } public bool ClientClose () { if (clientSocket == null || !clientSocket.Connected) { return false ; } try { clientSocket.Close(); return true ; } catch (Exception e) { Debug.Log("关闭客户端发生异常:" + e.ToString()); return false ; } } }
3.创建脚本”Loom.cs” 实现将线程中的获取到的服务器消息传递到主线程中 “Loom.cs”脚本挂在再Unity场景中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 using UnityEngine;using System.Collections.Generic;using System;using System.Threading;using System.Linq;public class Loom : MonoBehaviour { static bool isInitialized; private static Loom _ins; public static Loom ins { get { Initialize(); return _ins; } } void Awake () { _ins = this ; isInitialized = true ; } public static void Initialize () { if (!isInitialized) { if (!Application.isPlaying) return ; isInitialized = true ; var obj = new GameObject("Loom" ); _ins = obj.AddComponent<Loom>(); DontDestroyOnLoad(obj); } } struct NoDelayedQueueItem { public Action<object > action; public object param; } List<NoDelayedQueueItem> listNoDelayActions = new List<NoDelayedQueueItem>(); struct DelayedQueueItem { public Action<object > action; public object param; public float time; } List<DelayedQueueItem> listDelayedActions = new List<DelayedQueueItem>(); public static void QueueOnMainThread (Action<object > taction, object param ) { QueueOnMainThread(taction, param, 0f ); } public static void QueueOnMainThread (Action<object > action, object param, float time ) { if (time != 0 ) { lock (ins.listDelayedActions) { ins.listDelayedActions.Add(new DelayedQueueItem { time = Time.time + time, action = action, param = param }); } } else { lock (ins.listNoDelayActions) { ins.listNoDelayActions.Add(new NoDelayedQueueItem { action = action, param = param }); } } } List<NoDelayedQueueItem> currentActions = new List<NoDelayedQueueItem>(); List<DelayedQueueItem> currentDelayed = new List<DelayedQueueItem>(); void Update () { if (listNoDelayActions.Count > 0 ) { lock (listNoDelayActions) { currentActions.Clear(); currentActions.AddRange(listNoDelayActions); listNoDelayActions.Clear(); } for (int i = 0 ; i < currentActions.Count; i++) { currentActions[i].action(currentActions[i].param); } } if (listDelayedActions.Count > 0 ) { lock (listDelayedActions) { currentDelayed.Clear(); currentDelayed.AddRange(listDelayedActions.Where(d => Time.time >= d.time)); for (int i = 0 ; i < currentDelayed.Count; i++) { listDelayedActions.Remove(currentDelayed[i]); } } for (int i = 0 ; i < currentDelayed.Count; i++) { currentDelayed[i].action(currentDelayed[i].param); } } } void OnDisable () { if (_ins == this ) { _ins = null ; } } }
4.使用方法
1 2 SocketClient client = new SocketClient(ip, port); isConnect = client.ConnectServer();
-服务器端 在VisualStudio2022中添加以下脚本”SocketServer.cs”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 using System;using System.Collections.Generic;using System.Linq;using System.Net.Sockets;using System.Net;using System.Text;using System.Threading;using System.Threading.Tasks;public delegate void DelegateMsg (string Msg ) ;namespace WindowsFormsAppSocektServer { internal class SocketServer { private int SocketServerPort = 10001 ; private Thread acceptConnectReqThd; private Socket _clientSocket; private int MAX_SEND_FILE_LENGTH = 4096 ; public DelegateMsg delegateMsg; public bool Start (string _ip,int _port ) { try { Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ip = IPAddress.Parse(_ip); IPEndPoint port = new IPEndPoint(ip, _port); socketWatch.Bind(port); Console.WriteLine("监听成功" ); socketWatch.Listen(20 ); acceptConnectReqThd = new Thread(AcceptConnectReqHandler); acceptConnectReqThd.IsBackground = true ; acceptConnectReqThd.Start(socketWatch); return true ; } catch (Exception e) { return false ; } } private void AcceptConnectReqHandler (object _socket ) { try { Socket serverSocket = (Socket)_socket; while (true ) { Socket clientSocket = serverSocket.Accept(); Thread acceptMsgReqThd = new Thread(ReciveMsgReqHandler); acceptMsgReqThd.IsBackground = true ; acceptMsgReqThd.Start(clientSocket); } } catch (Exception e) { Console.WriteLine("服务端处理连接事件异常:" + e.ToString()); } } private void ReciveMsgReqHandler (object _socket ) { Socket clientSocket = (Socket)_socket; _clientSocket = clientSocket; try { while (true ) { if (clientSocket == null ) { continue ; } byte [] buffer = new byte [MAX_SEND_FILE_LENGTH]; Console.WriteLine("等待接受客户端的数据:" ); int dataLength = clientSocket.Receive(buffer); Console.WriteLine("接受到客户端的数据,字节数:" + dataLength); if (dataLength == 0 ) { break ; } string strMsg = Encoding.UTF8.GetString(buffer,0 , dataLength); Console.WriteLine("接受到客户端的消息:" + strMsg); delegateMsg(strMsg); } } catch (Exception e) { SocketException socketExp = e as SocketException; if (socketExp != null && socketExp.NativeErrorCode == 10054 ) { Console.WriteLine("socket客户端关闭:" + e.ToString()); } else { Console.WriteLine("======接受消息异常:" + e.ToString()); } } } public void SendToClient (string sendMsg ) { if (_clientSocket != null ) { byte [] buffer = Encoding.UTF8.GetBytes(sendMsg); _clientSocket.Send(buffer); } } } }
使用方法
1 2 socketServer = new SocketServer(); socketServer.Start(IP,Port);
下载地址: 链接:https://pan.baidu.com/s/167XeUUsulXHHtIdeIfhgeA?pwd=btvd 提取码:btvd