C# WebSocket - 握手期间客户端没有响应

Posted

技术标签:

【中文标题】C# WebSocket - 握手期间客户端没有响应【英文标题】:C# WebSocket - No response from client during handshake 【发布时间】:2017-06-13 14:19:10 【问题描述】:

我正在尝试为在浏览器输入时进行交互的应用程序编写 C# WebSocket 服务器。

这是代码:

class Program 
 static void Main(string[] args) 
  var listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 42001);
  listener.Start();
  using(var client = listener.AcceptTcpClient())
  using(var stream = client.GetStream())
  using(var reader = new StreamReader(stream))
  using(var writer = new StreamWriter(stream)) 
   while (!reader.EndOfStream) 
    String line = reader.ReadLine();

    if (new Regex("^GET").IsMatch(line)) 
     line = reader.ReadLine();
     if (new Regex("^Sec-WebSocket-Key: ").IsMatch(line)) 
      String key = new Regex("(^Sec-WebSocket-Key\\: |\\r\\n)").Replace(line, "");

      key = Convert.ToBase64String(SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")));

      writer.WriteLine("HTTP/1.1 101 Switching Protocols");
      writer.WriteLine("Upgrade: websocket");
      writer.WriteLine("Connection: Upgrade");
      writer.WriteLine("Sec-WebSocket-Accept: " + key);
      writer.WriteLine("Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits");
      writer.WriteLine("WebSocket-Origin: http://127.0.0.1");
      writer.WriteLine("WebSocket-Location: ws://localhost:42001/websocket");
      writer.WriteLine("");
     
    
   
  
  listener.Stop();
 

...和:

        var ws = new WebSocket('ws://localhost:42001/websocket');

        ws.onopen = function() 
            console.log('connected');
        ;

        ws.onmessage = function(e) 
            console.log(e.data);
        ;

        ws.onerror = function(e) 
            console.log(e);
        ;

        ws.onclose = function() 
            console.log("closed");
        ;

在执行时,TPCListener 成功接受 TCPClient 并读取传入的 HTTP 请求。它解析Key,生成正确的Accept 令牌,但是JS - window native - WebSocket 似乎已经彻底疯了:无论收到什么它都不会回答。 我希望它在发送HTTP/1.1 400 Bad Request 时会引发错误,但什么也没有发生。它只是静音。 查看 Chrome 开发工具的Networking 选项卡,我只看到 websocket 传出 GET 请求,但没有传入数据包 - 这应该发生吗? 如果我强行关闭应用程序,WebSocket 会抛出这个异常:

WebSocket connection to 'ws://localhost:42001/websocket' failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET.

我在这里缺少什么?提前谢谢大家。

另外,我没有使用 Net.WebSockets,因为它从 .NET 4.5 开始可用,并且我的应用程序针对从 Windows 7 到当前版本的 Windows 10 的系统。

【问题讨论】:

【参考方案1】:

嗯...您的 C# 代码能走多远?我的第一个赌注是缓冲 - 你不会刷新写入器或流,所以我会期望它们在卡在while 循环的顶部时保留数据,但坦率地说首先不应该是while 循环-每个套接字只能握手一次,而不是很多。您可以尝试在空白行之后添加刷新,并且您应该确保 Socket 本身已禁用缓冲 (NoDelay = true;) - 但是:从根本上说,这不是编写 web-socket 服务器的好方法。除此之外,如果握手成功,数据将不再是文本,因此拥有TextReader 是一件非常糟糕的事情。坦率地说,你应该在这里处理原始的 Socket / byte[] 数据,IMO(已经多次实现了这个东西)。

【讨论】:

您的第一个赌注非常正确,谢谢。我确实冲洗了作家并且手非常成功地握手 - 我很抱歉。我很感激这些提示! @Marc Gravell 既然您已经多次实现 WebSockets,您能否看看我的帖子并提供代码示例?我的帖子***.com/questions/47481999/…

以上是关于C# WebSocket - 握手期间客户端没有响应的主要内容,如果未能解决你的问题,请参考以下文章

WebSocket 握手期间出错:意外的响应代码:302

Apollo 2.x 客户端和服务器设置:WebSocket 握手期间出错?

WebSocket 握手期间出错:意外响应代码:503

webSocket 握手期间的错误意外响应代码:400

使用 C# 的 websocket 握手请求

websocket失败:WebSocket握手期间出错:意外响应代码:400