Mono C# 中的 wss WebSocket 服务器:SslStream 没有给我数据,但 Stream 有

wss WebSocket server in Mono C# : SslStream gives me no data but Stream do

几天以来,我一直在尝试让 (JS)wss/(c#)SslStream 连接正常工作,以便在单声道 c# 中创建 wss 服务器。

我的问题:当服务器接受传入的安全 WebSocket 连接时,我无法从中获取数据以开始握手过程。

到目前为止我做了什么:

  1. 我设置了一个 TCPListener 接受客户端给我一个 TCPClient 实例。
  2. 我从 TCPClient 获取流并从中创建一个 SslStream。
  3. 我用 AuthenticateAsServer(X509Certificate2) 同步验证它
  4. 我尝试读取数据失败

其他详细信息:

  1. 我注意到如果我使用 Stream 对象而不是 SslStream 对象,我会成功地从中获取数据(但按预期加密)
  2. 我测试了使用相同的 pfx 证书将我的 WebSoket 连接到相同的 adress/port 到 Fleck(也在我的盒子上用 Monodevelop 构建)并使其正常工作
  3. 我还注意到 Fleck 抛出消息说它收到 0 字节,然后关闭连接并(以某种方式)重新连接并从 [=69= 正确获取数据].
  4. 我没有收到任何错误,SslStream 似乎已正确验证
  5. 我在 https 中正确连接客户端并在同一程序中处理另一个端口上的请求

我的配置:

在此先感谢您的帮助!

监听代码:

   public void AudioListen ()
    {
        audioComListener.Start ();
        while (isAudioActive) {
            TcpClient s = audioComListener.AcceptTcpClient ();
            Stream clientStream;
            string hellostr;

            clientStream = getClientStream(s);

            if(debugCommuncation)
            {
                logToFileLine("(KEY) HandShaking begins with "+s.Client.RemoteEndPoint.ToString ().Split (':') [0]);
            }

            if(!WebSocketHandshake(clientStream))
            {
                if(debugCommuncation)
                {
                    logToFileLine("(KEY) (X) HandShake read 0 byte from "+s.Client.RemoteEndPoint.ToString ().Split (':') [0]);
                }

                s.Close();

                return;
            }
            else
            {
                logToFileLine("(KEY) HandShaking OK with "+s.Client.RemoteEndPoint.ToString ().Split (':') [0]);
            }

            hellostr=streamReadLine(clientStream);

            if(hellostr.IndexOf("hello:")==0)
            {
                string usrstr=hellostr.Split(':')[1];
                User usr= Users.GetUser(usrstr);


                if(usr!=null)
                {
                    usr.TcpC=s;

                    User usrdest=usr.corresp;

                    if( usrdest!=null && 
                        usrdest.ByPass==null && 
                        usrdest.TcpC!=null)
                    {
                        Stream clientStream2 = getClientStream(usrdest.TcpC);
                        usr.ByPass=new TCPByPass(clientStream,clientStream2);
                        usrdest.ByPass=usr.ByPass;
                    }                       

                }
            }

            Thread.Sleep (1);
        };
    }

获取 SslStream 的函数:

        private Stream getClientStream(TcpClient s,bool forceHTTP=false)
    {
        Stream clientStream;
        if(isSSL && !forceHTTP)
        {
            clientStream = new SslStream (s.GetStream ());
            ((SslStream)clientStream).AuthenticateAsServer(SrvCert);
            // Set timeouts for the read and write to 5 seconds.
            /**/clientStream.ReadTimeout = 5000;
            clientStream.WriteTimeout = 5000;

            //SecuDiag.MakeAllDiag(((SslStream)clientStream));
        }
        else
        {
            clientStream=s.GetStream ();
        }     

        return clientStream;   
    }

试图为握手目的获取数据的函数:

    public bool WebSocketHandshake(Stream clientStream)
    {
        string hellostr;

        // Here I test trying to get data (Also tried to use Stream.ReadByte())
        Byte[] toto=new Byte[2048];

        ((SslStream)clientStream).Read(toto,0,2048);

        if(toto[0]==0)return false;

        Console.WriteLine("#############################################");
        Console.WriteLine("toto array is {0} bytes long",toto.Length);
        for(int t =0;t<10;t++)
        {
            for(int u =0;u<10;u++)
            {
                Console.Write(toto[t*10+u].ToString());
            }
            Console.WriteLine(";");
        }
        Console.WriteLine("#############################################");

        // Trying to get data

        //hellostr=streamReadLine(clientStream);     

        //Console.WriteLine(hellostr);

        return true;
    }

我想我解决了问题。我不明白为什么,但我认为有必要在接受后立即关闭已接受的连接 iaoi 连接是 wss。 Websocket 将自动重新连接 :)