С тех пор я пытаюсь установить соединение (JS) wss / (c #) SslStream для создания сервера wss в моно c #.
Моя проблема: Когда сервер принимает неподходящее защищенное соединение WebSocket, я не могу получить от него данные, чтобы начать процесс рукопожатия.
Что я сделал до сих пор:
- Я установил TCPListener, который принимает клиента, предоставляющего мне экземпляр TCPClient.
- Я получаю поток от TCPClient и создаю из него SslStream.
- Я синхронно аутентифицирую его с помощью AuthenticateAsServer (X509Certificate2)
- Я безуспешно пытаюсь прочитать данные
Другие детали:
- Замечу, что если я использую объект Stream вместо объекта SslStream, мне удастся получить от него данные (но зашифрованные, как и ожидалось)
- Я проверил, чтобы подключить мой WebSoket к тому же адресу / порту к Fleck (встроенный в мою коробку с Monodevelop тоже), используя тот же сертификат pfx, и он работал правильно
- Я также отмечаю, что Fleck выбрасывает сообщения о том, что получает 0 байт, затем закрывает соединение и (каким-то образом) повторно подключает его и правильно получает данные из Socket / SslStream.
- Я не получаю никакой ошибки, похоже, что SslStream правильно аутентифицирован
- Я правильно подключаю клиентов в 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;
}