• Socket服务器-Websocket支持多端连入


    socket服务端:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Security.Cryptography;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using System.Threading.Tasks;
    namespace ConsoleApplication1
    {
        class Program
        {
            static List<Socket> Sockets = new List<Socket>();
            //static Socket listener = null;
            //static Dictionary<string, Socket> ClientConnectionItems = new Dictionary<string, 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();
                    }
                    //Thread threadwatch = new Thread(WatchConnecting);
                    //threadwatch.IsBackground = true;
                    ////启动线程         
                    //threadwatch.Start();
                    //Console.WriteLine("开启监听......");
                    //Console.ReadKey();
                    //listener.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
                Console.ReadLine();
            }
            //public static void WatchConnecting()
            //{
            //    Socket connection = null;
            //    while (true)//持续不断监听客户端发来的请求    
            //    {
            //        try
            //        {
            //            connection = listener.Accept();
            //        }
            //        catch (Exception) {
            //            Console.WriteLine();
            //            break;
            //        }
            //        //客户端网络结点号   
            //        string remoteEndPoint = connection.RemoteEndPoint.ToString();
            //        //添加客户端信息             
            //        ClientConnectionItems.Add(remoteEndPoint, connection);
            //        //显示与客户端连接情况           
            //        Console.WriteLine(" [客户端"" + remoteEndPoint + ""建立连接成功! 客户端数量:" + ClientConnectionItems .Count+ "]");
            //        //获取客户端的IP和端口号             
            //        IPAddress clientIP = (connection.RemoteEndPoint as IPEndPoint).Address;
            //        int clientPort = (connection.RemoteEndPoint as IPEndPoint).Port;
            //        //让客户显示"连接成功的"的信息             
            //        string sendmsg = "[" + "本地IP:" + clientIP + " 本地端口:" + clientPort.ToString() + " 连接服务端成功!]";
            //        byte[] arrSendMsg = Encoding.UTF8.GetBytes(sendmsg);
            //        connection.Send(arrSendMsg);
            //        //创建一个通信线程                 
            //        Thread thread = new Thread(recv);
            //        //设置为后台线程,随着主线程退出而退出            
            //        thread.IsBackground = true;
            //        //启动线程               
            //        thread.Start(connection);

            //    }
            //}
          
       
        /// <summary> 
        /// 接收客户端发来的信息,客户端套接字对象
        /// </summary>   
        /// <param name="socketclientpara"></param>
        //static void recv(object socketclientpara)
        //{
        //    Socket socketServer = socketclientpara as Socket;
        //    while (true)
        //    {
        //        //创建一个内存缓冲区,其大小为1024*1024字节  即1M
        //        byte[] arrServerRecMsg = new byte[1024 * 1024];
        //        //将接收到的信息存入到内存缓冲区,并返回其字节数组的长度 
        //        try
        //        {
        //            int length = socketServer.Receive(arrServerRecMsg);

        //            //将机器接受到的字节数组转换为人可以读懂的字符串     
        //            string strSRecMsg = Encoding.UTF8.GetString(arrServerRecMsg, 0, length);
        //            //将发送的字符串信息附加到文本框txtMsg上              
        //            Console.WriteLine(" [客户端:" + socketServer.RemoteEndPoint + " 时间:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "] " + strSRecMsg);
        //                //

        //                //Thread.Sleep(1000);
        //                //自定义聊天内容
        //                //Console.WriteLine("输入消息: ");
        //                //string s = Console.ReadLine();
        //                //单个客户端
        //                //socketServer.Send(Encoding.UTF8.GetBytes("[" + socketServer.RemoteEndPoint + "]:" + strSRecMsg + " "));
        //                //发送客户端数据           
        //                if (ClientConnectionItems.Count > 0)
        //            {
        //                foreach (var socketTemp in ClientConnectionItems)
        //                {
        //                    socketTemp.Value.Send(Encoding.UTF8.GetBytes("[" + socketServer.RemoteEndPoint + "]:" + strSRecMsg));
        //                }
        //            }
        //        }
        //        catch (Exception)
        //        {
        //            ClientConnectionItems.Remove(socketServer.RemoteEndPoint.ToString());
        //            //提示套接字监听异常     

        //            Console.WriteLine(" [客户端"" + socketServer.RemoteEndPoint + ""已经中断连接! 客户端数量:" + ClientConnectionItems.Count + "]");
        //            //关闭之前accept出来的和客户端进行通信的套接字          
        //            socketServer.Close();
        //            break;
        //        }
        //    }
        //}


        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;
                    }
                }


            }
            /// <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:(.*?) ");
                Match m = r.Match(handShakeText);
                if (m.Groups.Count != 0)
                {
                    key = Regex.Replace(m.Value, @"Sec-WebSocket-Key:(.*?) ", "$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;
            }
        }
    }

    websocket客户端:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits="SmartLockerWS.Test" %>

    <%--<!DOCTYPE html>

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
                <asp:Button ID="btnTest" runat="server" Text="Test1" OnClick="btnTest_Click" /><asp:Button ID="Button2" runat="server" Text="Test2" OnClick="btnTest2_Click" /><asp:Label ID="lbl1" runat="server" />
                <asp:GridView ID="gv1" runat="server" />
        </div>
        </form>
    </body>
    </html>--%>
    <!DOCTYPE html>

    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <title></title>
        <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>

    </head>

    <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>

    或者socket客户端:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;

    namespace ConsoleApplication2
    {
        class Program
        {
            //创建 1个客户端套接字 和1个负责监听服务端请求的线程 
            static Thread threadclient = null;
            static Socket socketclient = null;

            static void Main(string[] args)
            {
                //定义一个套接字监听 
                socketclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                //获取文本框中的IP地址 
                IPAddress address = IPAddress.Parse("127.0.0.1");

                //将获取的IP地址和端口号绑定在网络节点上 
                IPEndPoint point = new IPEndPoint(address, 10);

                try
                {
                    //客户端套接字连接到网络节点上,用的是Connect 
                    socketclient.Connect(point);
                }
                catch (Exception r)
                {
                    return;
                }

                threadclient = new Thread(recv);
                threadclient.IsBackground = true;
                threadclient.Start();
                Thread.Sleep(1000);
                Console.WriteLine(socketclient.LocalEndPoint+": ");
                while (true) {
                    string s = Console.ReadLine();
                    ClientSendMsg(s);
                }
            }

            // 接收服务端发来信息的方法   
           static void recv()
            {
                int x = 0;
                //持续监听服务端发来的消息
                while (true)
                {
                    try
                    {
                        //定义一个1M的内存缓冲区,用于临时性存储接收到的消息 
                        byte[] arrRecvmsg = new byte[1024 * 1024];

                        //将客户端套接字接收到的数据存入内存缓冲区,并获取长度 
                        int length = socketclient.Receive(arrRecvmsg);

                        //将套接字获取到的字符数组转换为人可以看懂的字符串 
                        string strRevMsg = Encoding.UTF8.GetString(arrRecvmsg, 0, length);
                        if (x == 1)
                        {
                            Console.WriteLine(strRevMsg);
                            }
                        else
                        {
                            Console.WriteLine(strRevMsg + " ");
                            x = 1;
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("远程服务器已经中断连接!" + ex.Message + " ");
                        break;
                    }
                }
            }

            //获取当前系统时间 
            DateTime GetCurrentTime()
            {
                DateTime currentTime = new DateTime();
                currentTime = DateTime.Now;
                return currentTime;
            }

            //发送字符信息到服务端的方法 
           static void ClientSendMsg(string sendMsg)
            {
                //将输入的内容字符串转换为机器可以识别的字节数组    
                byte[] arrClientSendMsg = Encoding.UTF8.GetBytes(sendMsg);
                //调用客户端套接字发送字节数组    
                socketclient.Send(arrClientSendMsg);
                //将发送的信息追加到聊天内容文本框中    
            } 
        }
    }

  • 相关阅读:
    重新整理数据结构与算法(c#)——算法套路迪杰斯特拉算法[三十一]
    重新整理数据结构与算法(c#)——算法套路k克鲁斯算法[三十]
    重新整理数据结构与算法(c#)——算法套路普利姆算法[二十九]
    arp 的概念解析
    什么是ip协议二
    什么是ip协议一
    python自动化报告的输出
    使用wxpy自动发送微信消息
    Pycharm2017常用快捷键
    【新番】不正经的魔术讲师与禁忌教典【全集更新中】
  • 原文地址:https://www.cnblogs.com/80028366local/p/12760667.html
Copyright © 2020-2023  润新知