繁体   English   中英

TCP html5 websocket客户端连接到C#套接字服务器

[英]TCP html5 websocket client connect to C# socket server

我有一个使用Socket用C#编写的服务器:

/*
    Richard D. Grant
    R.grant.jr.122193@gmail.com
    -Contact for details-
*/
using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.Threading;

namespace SERVER{
    static class Application{
        private static readonly List<Socket> _client_list = new List<Socket>();
        private const ushort _port = 8080, _buffer_len = 1024;
        private static byte[] _buf = new byte[_buffer_len];
        private static string key;
        static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";

        private static Boolean exiting = false;
        static int Main(){
            Console.Title = "Server Application";
            Socket server_socket = StartServer();
            while(!exiting){

            }
            return CloseServer(server_socket);
        }

        private static Socket StartServer(){
            IPEndPoint IPE = new IPEndPoint(IPAddress.Any, _port); // 192.168.0.14:80
            Socket server_socket = new Socket(IPE.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            server_socket.Bind(IPE);
            server_socket.Listen(128);
            server_socket.BeginAccept(AcceptCallback, server_socket);
            Console.WriteLine("Server Succeeded.");
            return server_socket;
        }
        private static void AcceptCallback(IAsyncResult AR){
            Console.WriteLine("accepting...");
            Socket server_socket = (Socket)AR.AsyncState;
            Socket client_socket = server_socket.EndAccept(AR);

            client_socket.BeginReceive(_buf, 0, _buffer_len, SocketFlags.None, RecCallback, client_socket);

            server_socket.BeginAccept(AcceptCallback, server_socket);
        }
        private static void RecCallback(IAsyncResult AR){
            Console.WriteLine("Recieving");
            Socket client_socket = (Socket)AR.AsyncState;

            int rec_len = client_socket.EndReceive(AR);

            byte[] rec_buf = new byte[rec_len];
            Array.Copy(_buf, rec_buf, rec_len);

            string rec_text = Encoding.UTF8.GetString(rec_buf);


                if(!_client_list.Contains(client_socket)){
                    _client_list.Add(client_socket);
                    key = rec_text.Replace("ey:", "`")
                    .Split('`')[1]                     // dGhlIHNhbXBsZSBub25jZQ== \r\n .......
                    .Replace("\r", "").Split('\n')[0]  // dGhlIHNhbXBsZSBub25jZQ==
                    .Trim();
                    var test1 = AcceptKey(ref key);

                    var newLine = "\r\n";

                    var response = "HTTP/1.1 101 Switching Protocols" + newLine
                         + "Upgrade: websocket" + newLine
                         + "Connection: Upgrade" + newLine
                         + "Sec-WebSocket-Accept: " + test1 + newLine + newLine
                         ;
                    client_socket.Send(Encoding.UTF8.GetBytes(response));
                    client_socket.Send("server received");
                }else{
                    Console.WriteLine(rec_text);
                }
            _buf = new byte[_buffer_len];
            client_socket.BeginReceive(_buf, 0, _buffer_len, SocketFlags.None, RecCallback, client_socket);
        }

        private static void client_disconnect(Socket soc){
            soc.Shutdown(SocketShutdown.Both);
            soc.Close();
        }
        private static ushort CloseServer(Socket server_socket){
            foreach(Socket client in _client_list){
                client_disconnect(client);
            }
            server_socket.Close();
            return 0;
        }

        private static string AcceptKey(ref string key){
            string longKey = key + guid;
            byte[] hashBytes = ComputeHash(longKey);
            return Convert.ToBase64String(hashBytes);
        }

        static SHA1 sha1 = SHA1CryptoServiceProvider.Create();
        private static byte[] ComputeHash(string str){
            return sha1.ComputeHash(Encoding.UTF8.GetBytes(str));
        }
    }
}

我有HTML5 websocket客户端:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script type="text/javascript">
        function connect() {
            var ws = new WebSocket("ws://localhost:8080/service");
            ws.onopen = function () {
                ws.send("Hello World"); // I WANT TO SEND THIS MESSAGE TO THE SERVER!!!!!!!!
                console.log("opened!");
            };

            ws.onmessage = function (evt) {
                console.log("About to receive data");
                var received_msg = evt.data;
                console.log("Message received = "+received_msg);
            };
            ws.onclose = function () {
                // websocket is closed.
                console.log("Connection is closed...");
            };
        };


    </script>
</head>
<body style="font-size:xx-large" >
    <div>
    <a href="#" onclick="connect()">Click here to start</a></div>
</body>
</html>

HTML5 websocket需要握手,服务器将对此进行相应处理。

client_socket.send(Encoding.UTF8.GetBytes("send"));

不触发html5 onmessage

ws.send("send");

将加扰的文本返回到服务器,但发送成功。

服务器处理握手,但此后不处理数据包帧。 该消息不会以纯文本形式发送回,并且需要进行一些处理。

如何在服务器端发送和接收WebSocket消息?

这详细说明了框架规格。 例如,第一个字节始终为129,秒数与长度有关。 有一个示例C#方法可对提供的链接上的帧进行解码。

我想将源代码发布到我的解决方案中,尽管我想赞扬AlexH将我指向正确的位置。

private static byte[] encode(string str){
     List<byte> lb = new List<byte>();
     lb.Add(0x81);//129 to represent text frame
     lb.Add((byte)str.Length);//2nd byte represents the length of the string
     lb.AddRange(System.Text.Encoding.UTF8.GetBytes(str));
     return lb.ToArray();
}

帧:

+---------------------------------+
| FRAME TYPE | DATA LENGTH | DATA |
+---------------------------------+

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM