C# Socket服务器及多客户端连接应用例程
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                C# Socket服务器及多客户端连接应用例程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                服務端代碼[控制臺示例]
static List<Socket> Sockets = new List<Socket>();static void Main(string[] args){int port = 10;byte[] buffer = new byte[1024];IPEndPoint localEP = new IPEndPoint(IPAddress.Any, port);Socket listener = new Socket(localEP.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);try{listener.Bind(localEP);listener.Listen(10);Console.WriteLine("等待客戶端連接....");while (true) //該操作用于多個客戶端連接{Socket sc = listener.Accept();//接受一個連接Sockets.Add(sc); //將連接的客戶端, 添加到內存當中Thread t = new Thread(new ThreadStart(() => ReceiveData(sc))); //開啟當前Socket線程, 去執行獲取數據的動作,與客戶端通信t.IsBackground = true;t.Start();}}catch (Exception e){Console.WriteLine(e.ToString());}Console.ReadLine();}public static void ReceiveData(Socket sc){byte[] buffer = new byte[1024];Console.WriteLine("接受到了客戶端:" + sc.RemoteEndPoint.ToString() + "連接....");//握手int length = sc.Receive(buffer);//接受客戶端握手信息sc.Send(PackHandShakeData(GetSecKeyAccetp(buffer, length)));while (true){try{//接受客戶端數據Console.WriteLine("等待客戶端數據....");length = sc.Receive(buffer);//接受客戶端信息string clientMsg = AnalyticData(buffer, length);Console.WriteLine("接受到客戶端數據:" + clientMsg);//發送數據string sendMsg = "服務端返回信息:" + clientMsg;sc.Send(PackData(sendMsg));}catch (Exception ex){Sockets.Remove(sc); //如果接收的過程中,斷開, 那么內存中移除當前Socket對象, 并且退出當前線程Console.WriteLine("客戶端已經斷開連接!");return;}}}Socket 相關類
/// <summary>/// 打包握手信息/// </summary>/// <param name="secKeyAccept"></param>/// <returns></returns>private static byte[] PackHandShakeData(string secKeyAccept){var responseBuilder = new StringBuilder();responseBuilder.Append("HTTP/1.1 101 Switching Protocols" + Environment.NewLine);responseBuilder.Append("Upgrade: websocket" + Environment.NewLine);responseBuilder.Append("Connection: Upgrade" + Environment.NewLine);responseBuilder.Append("Sec-WebSocket-Accept: " + secKeyAccept + Environment.NewLine + Environment.NewLine);return Encoding.UTF8.GetBytes(responseBuilder.ToString());}/// <summary>/// 生成Sec-WebSocket-Accept/// </summary>/// <param name="handShakeText">客戶端握手信息</param>/// <returns>Sec-WebSocket-Accept</returns>private static string GetSecKeyAccetp(byte[] handShakeBytes, int bytesLength){string handShakeText = Encoding.UTF8.GetString(handShakeBytes, 0, bytesLength);string key = string.Empty;Regex r = new Regex(@"Sec\-WebSocket\-Key:(.*?)\r\n");Match m = r.Match(handShakeText);if (m.Groups.Count != 0){key = Regex.Replace(m.Value, @"Sec\-WebSocket\-Key:(.*?)\r\n", "$1").Trim();}byte[] encryptionString = SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"));return Convert.ToBase64String(encryptionString);}/// <summary>/// 解析客戶端數據包/// </summary>/// <param name="recBytes">服務器接收的數據包</param>/// <param name="recByteLength">有效數據長度</param>/// <returns></returns>private static string AnalyticData(byte[] recBytes, int recByteLength){if (recByteLength < 2) { return string.Empty; }bool fin = (recBytes[0] & 0x80) == 0x80; // 1bit,1表示最后一幀 if (!fin){return string.Empty;// 超過一幀暫不處理 }bool mask_flag = (recBytes[1] & 0x80) == 0x80; // 是否包含掩碼 if (!mask_flag){return string.Empty;// 不包含掩碼的暫不處理}int payload_len = recBytes[1] & 0x7F; // 數據長度 byte[] masks = new byte[4];byte[] payload_data;if (payload_len == 126){Array.Copy(recBytes, 4, masks, 0, 4);payload_len = (UInt16)(recBytes[2] << 8 | recBytes[3]);payload_data = new byte[payload_len];Array.Copy(recBytes, 8, payload_data, 0, payload_len);}else if (payload_len == 127){Array.Copy(recBytes, 10, masks, 0, 4);byte[] uInt64Bytes = new byte[8];for (int i = 0; i < 8; i++){uInt64Bytes[i] = recBytes[9 - i];}UInt64 len = BitConverter.ToUInt64(uInt64Bytes, 0);payload_data = new byte[len];for (UInt64 i = 0; i < len; i++){payload_data[i] = recBytes[i + 14];}}else{Array.Copy(recBytes, 2, masks, 0, 4);payload_data = new byte[payload_len];Array.Copy(recBytes, 6, payload_data, 0, payload_len);}for (var i = 0; i < payload_len; i++){payload_data[i] = (byte)(payload_data[i] ^ masks[i % 4]);}return Encoding.UTF8.GetString(payload_data);}/// <summary>/// 打包服務器數據/// </summary>/// <param name="message">數據</param>/// <returns>數據包</returns>private static byte[] PackData(string message){byte[] contentBytes = null;byte[] temp = Encoding.UTF8.GetBytes(message);if (temp.Length < 126){contentBytes = new byte[temp.Length + 2];contentBytes[0] = 0x81;contentBytes[1] = (byte)temp.Length;Array.Copy(temp, 0, contentBytes, 2, temp.Length);}else if (temp.Length < 0xFFFF){contentBytes = new byte[temp.Length + 4];contentBytes[0] = 0x81;contentBytes[1] = 126;contentBytes[2] = (byte)(temp.Length & 0xFF);contentBytes[3] = (byte)(temp.Length >> 8 & 0xFF);Array.Copy(temp, 0, contentBytes, 4, temp.Length);}else{// 暫不處理超長內容 }return contentBytes;}客戶端連接[網頁測試]
 <!DOCTYPE html>
 ?
WebSocket客戶端示例
?請輸入一些文字
建立連接
發送數據
斷開連接
?
?
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>WebSockets客戶端示例</title> </head> <script> var webSocket; function connect() {try{var readyState = new Array("正在連接","已建立連接","正在關閉連接","已關閉連接");var host = "ws://localhost:10";webSocket = new WebSocket(host);var message = document.getElementById("message");message.innerHTML +="<p>Socket狀態:" + readyState[webSocket.readyState] + "</p>";webSocket.onopen = function(){message.innerHTML += "<p>Socket狀態:" + readyState[webSocket.readyState] + "</p>";}webSocket.onmessage = function(msg){message.innerHTML +="<p>接收信息:" + msg.data + "</p>";}webSocket.onclose=function(){message.innerHTML +="<p>Socket狀態:" + readyState[webSocket.readyState] + "</p>";}}catch(exception){message.innerHTML += "<p>有錯誤發生</p>";} } function send() {var text = document.getElementById("text").value;var message = document.getElementById("message");if(text == ""){message.innerHTML += "<p>請輸入一些文字</p>";return ;}try{webSocket.send(text);message.innerHTML += "<p>發送數據:" +text + "</p>";}catch(exception){message.innerHTML += "<p>發送數據出錯</p>";}document.getElementById("text").value=""; } function disconnect() {webSocket.close(); } </script> <body> <h1>WebSocket客戶端示例</h1> <div id="message"></div> <p>請輸入一些文字</p> <input id="text" type="text"> <button id="connect" onClick="connect();">建立連接</button> <button id="send" onClick="send();">發送數據</button> <button id="disconnect" onClick="disconnect();">斷開連接</button> </body> </html>總結
以上是生活随笔為你收集整理的C# Socket服务器及多客户端连接应用例程的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Node.js 多版本安装配置(Wind
- 下一篇: 解决:Failed to execute
