Сервер wss WebSocket в Mono C #: SslStream не дает мне никаких данных, но Stream делает - PullRequest
0 голосов
/ 02 ноября 2018

С тех пор я пытаюсь установить соединение (JS) wss / (c #) SslStream для создания сервера wss в моно c #.

Моя проблема: Когда сервер принимает неподходящее защищенное соединение WebSocket, я не могу получить от него данные, чтобы начать процесс рукопожатия.

Что я сделал до сих пор:

  1. Я установил TCPListener, который принимает клиента, предоставляющего мне экземпляр TCPClient.
  2. Я получаю поток от TCPClient и создаю из него SslStream.
  3. Я синхронно аутентифицирую его с помощью AuthenticateAsServer (X509Certificate2)
  4. Я безуспешно пытаюсь прочитать данные

Другие детали:

  1. Замечу, что если я использую объект Stream вместо объекта SslStream, мне удастся получить от него данные (но зашифрованные, как и ожидалось)
  2. Я проверил, чтобы подключить мой WebSoket к тому же адресу / порту к Fleck (встроенный в мою коробку с Monodevelop тоже), используя тот же сертификат pfx, и он работал правильно
  3. Я также отмечаю, что Fleck выбрасывает сообщения о том, что получает 0 байт, затем закрывает соединение и (каким-то образом) повторно подключает его и правильно получает данные из Socket / SslStream.
  4. Я не получаю никакой ошибки, похоже, что SslStream правильно аутентифицирован
  5. Я правильно подключаю клиентов в https и обрабатываю запросы на другом порту в той же программе

Моя конфигурация:

  • ОС: ArchLinux
  • C #: Mono .Net Framework 4.7
  • Браузеры (Chromium & Firefox)

    Несмотря на все мои исследования, которые я до сих пор не нашел, возможно, кто-то может помочь мне задаться вопросом, что мне здесь не хватает ...

Заранее спасибо за любую помощь!

Код прослушивания:

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

Функция, которая пытается получить данные для цели hanshake:

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

1 Ответ

0 голосов
/ 02 ноября 2018

Я думаю, что решил проблему. Я не понимаю, почему, но я думаю, что необходимо закрыть принятое соединение сразу после его принятия. Iaoi соединение wss. Сетевая розетка автоматически подключится:)

...