您好,登錄后才能下訂單哦!
先看看測試結果:
服務端:
服務器端控制臺:
可以發現我服務端連了2個客戶端,第一個為局域網的一臺機器,另一個為服務器的主機
ip為192.168.1.105 ,端口為42794的客戶端:
ip為192.168.1.104,端口為30547的客戶端:
需要發送聊天信息 : 使用“chat:”作為前綴。
值得注意的是 : 本文只探討異步Socket的封裝 , 包括包頭和包 。對與體驗效果不好,不是此次討論的范圍,Sorry。
一,核心 :
①:關于消息的構建類庫:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SocketTool { public sealed class SocketMsgTool { /// <summary> /// 構造一個發送包 /// </summary> /// <param name="mainCode">主碼</param> /// <param name="subCode">分碼</param> /// <param name="type">類型碼</param> /// <param name="Body">包體</param> /// <returns></returns> public static byte[] Creat_Msg(ushort mainCode, ushort subCode, ushort type, byte[] Body) { List<byte> cur = new List<byte>(Body); cur.InsertRange(0, BitConverter.GetBytes(mainCode)); cur.InsertRange(2, BitConverter.GetBytes(subCode)); cur.InsertRange(4, BitConverter.GetBytes(type)); ushort body_len = Convert.ToUInt16(Body.Length); cur.InsertRange(6, BitConverter.GetBytes(body_len)); return cur.ToArray<byte>(); } /// <summary> /// 獲取主碼 /// </summary> /// <param name="msg"></param> /// <returns></returns> public static ushort Get_MainCode(byte[] msg) { return BitConverter.ToUInt16(msg, 0); } /// <summary> /// 獲取分碼 /// </summary> /// <param name="msg"></param> /// <returns></returns> public static ushort Get_SubCode(byte[] msg) { return BitConverter.ToUInt16(msg, 2); } /// <summary> /// 獲取類型碼 /// </summary> /// <param name="msg"></param> /// <returns></returns> public static ushort Get_Type(byte[] msg) { return BitConverter.ToUInt16(msg, 4); } /// <summary> /// 獲取包體 /// </summary> /// <param name="msg"></param> /// <returns></returns> public static byte[] Get_Body(byte[] msg) { byte[] body = new byte[BitConverter.ToUInt16(msg, 6)]; Array.Copy(msg, 8, body, 0, body.Length); return body; } } }
②關于字節數組方法的擴展:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Async_Svr_Socket_Lib.com { /// <summary> /// 字節數組(byte[])的方法擴展 /// </summary> internal static class ByteArr_Fun_Extends { /// <summary> /// 追加數據到Buffer /// </summary> /// <param name="buffer"></param> /// <param name="buffer_off_index">數據的偏移下標</param> /// <param name="add">增加的byte[]</param> /// <returns>需要增加的size量</returns> public static int Push_Data(this byte[] buffer, ref int buffer_off_index, byte[] add) { int cur_con_count = buffer.Length - ( buffer_off_index + 1 ); if (add.Length > cur_con_count) { //需要擴大buffer的size int off = add.Length - cur_con_count; Array.Resize<byte>(ref buffer, buffer.Length + off);//擴充buffer的size add.CopyTo(buffer, buffer_off_index + 1); buffer_off_index += add.Length;//更新偏移 return off; } else { //不需要擴大buffer的size add.CopyTo(buffer, buffer_off_index + 1); buffer_off_index += add.Length;//更新偏移 return 0; } } /// <summary> /// 壓人新的數據(一般為包頭) - 構造新的發送包 /// </summary> /// <param name="buffer_send">需要發送的包體</param> /// <param name="unshift">壓入增加的byte[]</param> /// <returns>需要增加的size量</returns> public static void Unshift_Data(this byte[] buffer_send , byte[] unshift) { byte[] effective = buffer_send.Skip<byte>(0).Take<byte>(buffer_send.Length).ToArray<byte>(); List<byte> list = new List<byte>(effective); list.InsertRange(0, unshift);//頭部插入 buffer_send = list.ToArray();//重新指定數據 } /// <summary> /// 獲取當前數據(取出一個完整的包) /// </summary> /// <param name="buffer"></param> /// <param name="buffer_off_index">數據的偏移下標</param> /// <param name="cur_len">整個包的長度</param> /// <returns>當前的包</returns> public static byte[] Shift_Data(this byte[] buffer, ref int buffer_off_index, int cur_len) { byte[] next_buffer = null; if (cur_len < buffer_off_index + 1) next_buffer = buffer.Skip<byte>(cur_len - 1).Take<byte>(buffer_off_index + 1 - cur_len).ToArray<byte>();//下一個包(存在粘包) byte[] cur_buffer = buffer.Skip<byte>(0).Take<byte>(cur_len).ToArray<byte>();//當前的包(完整) if (next_buffer == null) buffer_off_index = -1; else { Array.Resize<byte>(ref buffer, next_buffer.Length); next_buffer.CopyTo(buffer, 0);//注入新的包 buffer_off_index = next_buffer.Length - 1; } return cur_buffer; } } }
③關于服務端Socket類庫:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading; using Async_Svr_Socket_Lib.com; using System.ComponentModel; namespace Async_Svr_Socket_Lib { /// <summary> /// 服務器Socket封裝 /// </summary> public sealed class Svr_Socket { private Socket _listener = null;//服務器Socket private readonly IPEndPoint _ip_point = null; private Action<Socket_CallBack_Type, Object, Socket> _callback = null;//回調函數 private readonly int _connect_count = 0; private readonly int _state_object_bufferlen = 0; private ManualResetEvent allDone = null;//信號量 private Timer _heart_beat_timer = null;//心跳包及時機制 /// <summary> /// 構造函數 /// </summary> /// <param name="ip_point">服務端ip+port</param> /// <param name="callback">回調函數</param> /// <param name="connect_count">可連接的服務端個數</param> /// <param name="state_object_bufferlen">client buffer長度</param> public Svr_Socket(IPEndPoint ip_point, Action<Socket_CallBack_Type, Object, Socket> callback, int connect_count = 100, int state_object_bufferlen = 512) { this._ip_point = ip_point; this._callback = callback; this._connect_count = connect_count; this._state_object_bufferlen = state_object_bufferlen; } /// <summary> /// 請求連接Socket服務器 /// </summary> public void Accept() { this._listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//構建Tcp通訊 allDone = new ManualResetEvent(false); try { this._listener.Bind(this._ip_point); this._listener.Listen(this._connect_count); while (true)//持續的監聽連接 { allDone.Reset();//置為無信號狀態 this._listener.BeginAccept(new AsyncCallback(this.Async_Accept_Callback), this._listener); allDone.WaitOne();//當前線程等待 } } catch (Exception e) { Console.WriteLine("Socket Error! -> {0}" , e.Message); } } //連接異步回調處理 private void Async_Accept_Callback(IAsyncResult ar) { allDone.Set();//置為有信號狀態 Socket listener = (Socket)ar.AsyncState; try { Socket client = listener.EndAccept(ar); State_Object state = new State_Object(this._state_object_bufferlen); state.Client_Socket = client; this._callback(Socket_CallBack_Type.connect_succ, true, client);//連接成功 this.receive(state); } catch (Exception e) { this._callback(Socket_CallBack_Type.connect_fail, e, null); } } //接收字節 private void receive(State_Object state) { state.Client_Socket.BeginReceive(state.Buffer, state.Buffer_Off_Index + 1, state.Buffer.Length - (state.Buffer_Off_Index + 1), 0, new AsyncCallback(this.Async_Receive_Callback), state); } //接收異步回調處理 private void Async_Receive_Callback(IAsyncResult ar) { State_Object state = (State_Object)ar.AsyncState; try { int byte_read_count = state.Client_Socket.EndReceive(ar);//接收的字節數 if (byte_read_count > 0) { state.Buffer_Off_Index += byte_read_count; this.Receive_Handler(state); } else { //玩家主動關閉了連接 this._callback(Socket_CallBack_Type.client_active_off, null, state.Client_Socket); } } catch( Exception e ) { //玩家被迫斷開(客戶端沒發送斷開指令) this._callback(Socket_CallBack_Type.client_passive_off, e, state.Client_Socket); } } /// <summary> /// 處理了粘包及斷包 /// </summary> /// <param name="state"></param> private void Receive_Handler(State_Object state ) { byte[] client_buffer = state.Buffer; if (state.Buffer_Off_Index + 1 >= 8)//如果包頭取到 { ushort body_len = BitConverter.ToUInt16(state.Buffer, 6); ushort packet_all_len = Convert.ToUInt16(body_len + 8); if (packet_all_len <= state.Buffer_Off_Index + 1) { int buffer_off_index = state.Buffer_Off_Index; byte[] cur_packet = state.Buffer.Shift_Data(ref buffer_off_index, packet_all_len);//取出當前的包(一整個包) state.Buffer_Off_Index = buffer_off_index;//重新賦值 this._callback( Socket_CallBack_Type.receive, cur_packet, state.Client_Socket);//回調接收到的包 if (state.Buffer_Off_Index == -1) { Array.Resize<byte>(ref client_buffer, this._state_object_bufferlen);//再次初始化buffer this.receive(state); } else { this.Receive_Handler(state); } } else if (packet_all_len > state.Buffer.Length)//當包長大于buffer時 { Array.Resize<byte>(ref client_buffer, state.Buffer.Length + this._state_object_bufferlen); this.receive(state); } else { this.receive(state); } } else { this.receive(state); } } /// <summary> /// 發送信息 /// </summary> /// <param name="socket"></param> /// <param name="msg">要發送的信息</param> public void Send(Socket socket, byte[] msg) { if (socket != null && socket.Connected) { socket.BeginSend(msg, 0, msg.Length, 0, new AsyncCallback(this.Async_Send_Callback), socket); } } //發送信息返回 private void Async_Send_Callback(IAsyncResult ar) { Socket socket = (Socket)ar.AsyncState; int byte_send_count = socket.EndSend(ar); this._callback(Socket_CallBack_Type.send, byte_send_count, socket); } } /// <summary> /// Socket回調類型 /// </summary> public enum Socket_CallBack_Type : uint { [Description("連接成功")] connect_succ = 0, [Description("連接失敗")] connect_fail = 1, [Description("接收返回")] receive = 2, [Description("發送返回")] send = 3, [Description("客戶端被迫斷開")] client_passive_off = 4, [Description("客戶端主動斷開")] client_active_off = 5 } }
④關于客戶端Socket類庫:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Net; using Async_Cli_Socket_Lib.com; using System.ComponentModel; namespace Async_Cli_Socket_Lib { /// <summary> /// 客戶端socket /// </summary> public sealed class Cli_Socket { private Socket _client = null; private IPEndPoint _ip_point = null; private Action<Socket_CallBack_Type , Object> _callback = null; private readonly int _state_object_bufferlen = 0; private State_Object _state = null; /// <summary> /// /// </summary> /// <param name="ip_point">服務端ip+port</param> /// <param name="callback">回調函數</param> /// <param name="state_object_bufferlen">buffer默認size</param> public Cli_Socket(IPEndPoint ip_point, Action<Socket_CallBack_Type, Object> callback, int state_object_bufferlen = 512) { this._ip_point = ip_point; this._callback = callback; this._state_object_bufferlen = state_object_bufferlen; this._state = new State_Object(state_object_bufferlen); } /// <summary> /// 獲取Socket /// </summary> public Socket Client { get { return this._client; } } public void Connect() { if (_client == null) _client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _client.BeginConnect(this._ip_point, new AsyncCallback(this.Async_Connect_Callback), _client); } private void Async_Connect_Callback(IAsyncResult ar) { Socket client = (Socket)ar.AsyncState; try { client.EndConnect(ar); this._callback(Socket_CallBack_Type.connect_succ, true); this.receive();//開始接收數據 } catch (Exception e) { this._callback(Socket_CallBack_Type.connect_fail, e); } } //開始接收數據 private void receive() { this._client.BeginReceive(this._state.Buffer, this._state.Buffer_Off_Index + 1, this._state.Buffer.Length - (this._state.Buffer_Off_Index + 1), 0, new AsyncCallback(this.Async_Receive_Callback), this._state); } //接收數據返回 private void Async_Receive_Callback(IAsyncResult ar) { State_Object state = (State_Object)ar.AsyncState; try { int byte_read_count = this._client.EndReceive(ar);//接收的字節數 if (byte_read_count > 0) { state.Buffer_Off_Index += byte_read_count;//增加的數據量 this.Receive_Handler(state); } else { this._callback(Socket_CallBack_Type.server_active_off, this._client); } } catch (Exception e) { this._callback(Socket_CallBack_Type.server_passive_off, e); } } private void Receive_Handler(State_Object state) { byte[] client_buffer = state.Buffer; if (state.Buffer_Off_Index + 1 >= 8)//包頭的信心已經收到 { ushort body_len = BitConverter.ToUInt16(state.Buffer, 6); ushort packet_all_len = Convert.ToUInt16(body_len + 8); if (packet_all_len <= state.Buffer_Off_Index + 1) { int buffer_off_index = state.Buffer_Off_Index; byte[] cur_packet = state.Buffer.Shift_Data(ref buffer_off_index, packet_all_len);//取出當前的包(一整個包) state.Buffer_Off_Index = buffer_off_index;//重新賦值 this._callback(Socket_CallBack_Type.receive ,cur_packet);//回調接收到的包------------------ if (state.Buffer_Off_Index == -1) { Array.Resize<byte>(ref client_buffer, this._state_object_bufferlen);//再次初始化buffer this.receive(); } else { this.Receive_Handler(state); } } else if (packet_all_len > state.Buffer.Length) { Array.Resize<byte>(ref client_buffer, state.Buffer.Length + this._state_object_bufferlen); this.receive(); } else { this.receive(); } } else { this.receive(); } } /// <summary> /// 發送Socket請求 /// </summary> /// <param name="msg">請求信息</param> public void Send(byte[] msg) { _client.BeginSend(msg, 0, msg.Length, 0, new AsyncCallback(this.Async_Send_Callback), this._state); } private void Async_Send_Callback(IAsyncResult ar) { State_Object state = (State_Object)ar.AsyncState; int byte_send_count = this._client.EndSend(ar);//發送了多少字節 this._callback(Socket_CallBack_Type.send, byte_send_count); } } /// <summary> /// Socket回調類型 /// </summary> public enum Socket_CallBack_Type : uint { [Description("連接成功")] connect_succ = 0, [Description("連接失敗")] connect_fail = 1, [Description("接收返回")] receive = 2, [Description("發送返回")] send = 3, [Description("服務端被迫斷開")] server_passive_off = 4, [Description("服務端主動斷開")] server_active_off = 5 } }
⑤:服務端 state_object
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; namespace Async_Svr_Socket_Lib.com { /// <summary> /// Socket數據 /// </summary> internal sealed class State_Object { /// <summary> /// Client Socket /// </summary> public Socket Client_Socket { set; get; } private byte[] _buffer = null; private int _buffer_off_index = -1; /// <summary> /// 構造函數 /// </summary> /// <param name="buffer_size">緩存初始的字節數</param> public State_Object(int buffer_size = 512) { this._buffer = new byte[buffer_size]; this.Buffer_Off_Index = -1; } /// <summary> /// 字節數組 /// </summary> public byte[] Buffer { get { return this._buffer; } } /// <summary> /// 緩存已經存儲的下標( 顯然從0開始 , -1表示沒有數據 ) /// </summary> public int Buffer_Off_Index { set { this._buffer_off_index = value; } get { return this._buffer_off_index; } } } }
⑥:客戶端state_object
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Async_Cli_Socket_Lib.com { /// <summary> /// Socket數據 /// </summary> internal sealed class State_Object { private byte[] _buffer = null; private int _buffer_off_index = -1; /// <summary> /// 構造函數 /// </summary> /// <param name="buffer_size">緩存初始的字節數</param> public State_Object(int buffer_size = 512) { this._buffer = new byte[buffer_size]; this.Buffer_Off_Index = -1; } /// <summary> /// 字節數組 /// </summary> public byte[] Buffer { get { return this._buffer; } } /// <summary> /// 緩存已經存儲的下標( 顯然從0開始 , -1表示沒有數據 ) /// </summary> public int Buffer_Off_Index { set { this._buffer_off_index = value; } get { return this._buffer_off_index; } } } }
二,測試(使用控制臺)
①:服務端
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Async_Svr_Socket_Lib; using System.Net; using System.Net.Sockets; using SocketTool; using System.Diagnostics; using System.Threading; namespace Server_Socket_Test { class Program { private Dictionary<string,Socket> _client_list = null;//因為測試的環境原因 , 使用 key :姓名 , 在真實的開發中應該使用用戶的ID號 private Svr_Socket _socket = null;//本人封裝的服務端Socket static void Main(string[] args) { Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.Green; Thread.CurrentThread.IsBackground = true;//退出后自動殺死進程 IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("192.168.1.104"), 6065); Program pro = new Program(); pro._socket = new Svr_Socket(ipe, pro.CallBack); Console.WriteLine("等待請求連接......."); pro._socket.Accept(); Console.Read(); } private void CallBack(Socket_CallBack_Type type , object msg, Socket client) { string key = String.Empty; switch (type) { case Socket_CallBack_Type.connect_succ: this.connect(msg , client); break; case Socket_CallBack_Type.connect_fail: Console.WriteLine("連接失敗 : {0}", ((Exception)msg).Message); break; case Socket_CallBack_Type.receive: this.receive(msg, client); break; case Socket_CallBack_Type.send: //Console.WriteLine("發送的字節數 : {0}", Convert.ToInt32(msg)); break; case Socket_CallBack_Type.client_active_off://主動下線 #if DEBUG Console.WriteLine("{0} 下線了 !!", client.RemoteEndPoint); #endif this.RemoveClient(client); break; case Socket_CallBack_Type.client_passive_off://被迫下線 #if DEBUG Console.WriteLine("{0} 下線了 !!", client.RemoteEndPoint); #endif this.RemoveClient(client); break; } } /// <summary> /// 玩家下線 /// </summary> /// <param name="client"></param> private void RemoveClient(Socket client) { if (this._client_list == null) return; string remove_name = string.Empty; foreach (KeyValuePair<string, Socket> kv in this._client_list) { if (kv.Value == client) { remove_name = kv.Key; break; } } this._client_list.Remove(remove_name); if (client != null && client.Connected) { client.Shutdown(SocketShutdown.Both); client.Close(); } if (this._client_list.Count > 0) { string remove_msg = "{0},下線了!!!"; byte[] msg = Encoding.UTF8.GetBytes(string.Format(remove_msg, remove_name)); msg = SocketMsgTool.Creat_Msg(1, 1, 3, msg); foreach (KeyValuePair<string, Socket> kv in this._client_list) { kv.Value.Send(msg); } } } /// <summary> /// 玩家上線 /// </summary> /// <param name="body"></param> /// <param name="client"></param> private void AddClient( byte[] body , Socket client) { string str = Encoding.UTF8.GetString(body); string name = str.Split(new char[] { ',' })[0]; Console.WriteLine("{0} > {1}", client.RemoteEndPoint, str); //開始啟動服務端的心跳包 if (this._client_list == null) this._client_list = new Dictionary<string, Socket>(); if (!this._client_list.ContainsKey(name)) this._client_list.Add(name, client); string add_msg = "{0},上線了!!!"; byte[] msg = Encoding.UTF8.GetBytes(string.Format(add_msg, name)); msg = SocketMsgTool.Creat_Msg(1, 1, 4, msg); foreach (KeyValuePair<string, Socket> kv in this._client_list) { kv.Value.Send(msg); } } private void connect(object msg , Socket client) { Console.WriteLine("連接成功 client ip : {0}" , client.RemoteEndPoint); byte[] welcome = Encoding.UTF8.GetBytes(String.Format("歡迎 : {0} , 尊姓大名?", client.RemoteEndPoint)); welcome = SocketMsgTool.Creat_Msg(1, 1, 1, welcome); client.Send(welcome); } private void receive(object msg, Socket client) { byte[] data = (byte[])msg; ushort mainCode = SocketMsgTool.Get_MainCode(data); ushort subCode = SocketMsgTool.Get_SubCode(data); ushort type = SocketMsgTool.Get_Type(data); byte[] body = SocketMsgTool.Get_Body(data); switch (mainCode) { case 1: switch (subCode) { case 0:// break; case 1: switch (type) { case 2: this.AddClient(body, client); break; } break; } break; case 2: switch (subCode) { case 1: switch (type) { case 1://聊天信息 this.Chat(body, client); break; } break; } break; } } /// <summary> /// 聊天處理 /// </summary> /// <param name="body"></param> /// <param name="client"></param> private void Chat(byte[] body, Socket client) { string msg = Encoding.UTF8.GetString(body); byte[] all_mag = SocketMsgTool.Creat_Msg(2, 1, 1, body); foreach (KeyValuePair<string, Socket> kv in this._client_list) { if (kv.Value != client) { kv.Value.Send(all_mag);//發送聊天信息 } } Console.WriteLine(msg); } } }
②,客戶端
using System; using System.Text; using System.Net; using Async_Cli_Socket_Lib; using SocketTool; using System.Net.Sockets; using System.Threading; namespace Client_Socket_Test { class Program { private Cli_Socket _socket = null; private readonly string _name = string.Empty; public Program(string name) { this._name = name; } static void Main(string[] args) { Console.BackgroundColor = ConsoleColor.Black; Console.ForegroundColor = ConsoleColor.Green; Thread.CurrentThread.IsBackground = true;//退出后自動殺死進程 Console.Write("請輸入用戶名:"); string name = Console.ReadLine(); IPEndPoint ipe = new IPEndPoint(IPAddress.Parse("192.168.1.104"), 6065); Program pro = new Program(name); pro._socket = new Cli_Socket(ipe, pro.CallBack); Console.WriteLine("請求連接Socket服務器"); pro._socket.Connect(); string code = Console.ReadLine(); while(true) { if (code.Trim().ToLower() == "off") { pro._socket.Client.Shutdown(SocketShutdown.Both); pro._socket.Client.Close(); break; } else { //聊天信息 if (code.Trim() != string.Empty && code.Trim().Substring(0,5) == "chat:") { pro.Chat(code.Trim().Substring(5));//發送聊天信息 } code = Console.ReadLine(); } } } /// <summary> /// 發送聊天信息 /// </summary> /// <param name="msg"></param> private void Chat(string chats) { string msg = string.Format("{0} 說 : {1}", _name, chats); byte[] by = SocketMsgTool.Creat_Msg(2,1,1,Encoding.UTF8.GetBytes(msg)); this._socket.Send(by); } private void CallBack( Socket_CallBack_Type type , Object msg ) { switch (type) { case Socket_CallBack_Type.connect_succ: this.connect(msg); break; case Socket_CallBack_Type.connect_fail: Console.WriteLine("連接失敗 : {0}", ((Exception)msg).Message); break; case Socket_CallBack_Type.receive: this.receive(msg); break; case Socket_CallBack_Type.send: Console.WriteLine("發送的字節數 : {0}", Convert.ToInt32(msg)); break; case Socket_CallBack_Type.server_active_off: #if DEBUG Console.WriteLine("主動 : 服務器斷開連接 : {0}", (msg as Exception).Message); #endif if (_socket.Client != null && _socket.Client.Connected) { _socket.Client.Shutdown(SocketShutdown.Both); _socket.Client.Close(); } break; case Socket_CallBack_Type.server_passive_off: #if DEBUG Console.WriteLine("被迫 : 服務器斷開連接 : {0}", (msg as Exception).Message); #endif if (_socket.Client != null && _socket.Client.Connected) { _socket.Client.Shutdown(SocketShutdown.Both); _socket.Client.Close(); } break; } } private void connect(object msg) { Console.WriteLine("已經成功連接到了Socket服務器了"); } private void receive(object msg) { byte[] data = (byte[])msg; ushort mainCode = SocketMsgTool.Get_MainCode(data); ushort subCode = SocketMsgTool.Get_SubCode(data); ushort type = SocketMsgTool.Get_Type(data); byte[] body = SocketMsgTool.Get_Body(data); switch (mainCode) { case 1: switch (subCode) { case 1: switch (type) { case 0: break; case 1: //Console.WriteLine(Encoding.UTF8.GetString(body)); byte[] hello = Encoding.UTF8.GetBytes(string.Format("{0},請多指教" , this._name)); Console.WriteLine("{0},請多指教", this._name); hello = SocketMsgTool.Creat_Msg(1, 1, 2, hello); this._socket.Send(hello); break; case 3://有玩家下線 string remove_news = string.Format("【{0}】:{1}", "Server", Encoding.UTF8.GetString(body)); Console.WriteLine(remove_news); break; case 4://有玩家上線 string add_msg = Encoding.UTF8.GetString(body); string add_name = add_msg.Split(new char[] { ',' })[0]; if (add_name != _name) { add_msg = string.Format("【{0}】:{1}", "Server", add_msg); Console.WriteLine(add_msg); } break; } break; } break; case 2: switch (subCode) { case 1: switch (type) { case 1://聊天信息 //Console.Clear(); string chat = Encoding.UTF8.GetString(body); Console.WriteLine(chat); break; } break; } break; } } } }
值得注意的是 : 此封裝不僅可以用于聊天,body也可以進行加密,用于游戲Socket通訊。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。