TCP html5 websocket客户端连接到c# socket服务器

TCP html5 websocket client connect to C# socket server

本文关键字:socket 服务器 连接 html5 websocket 客户端 TCP      更新时间:2023-09-26

我有一个使用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 |
+---------------------------------+