C# WebSocket - 握手期间客户端无响应 [英] C# WebSocket - No response from client during handshake

查看:87
本文介绍了C# WebSocket - 握手期间客户端无响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm attempting to write a C# WebSocket server for an application that interacts upon browser input.

这是代码:

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 原生 - WebSocket 似乎已经完全疯了:它确实如此无论收到什么都不会回答.我希望它在发送 HTTP/1.1 400 Bad Request 时抛出错误,但什么也没有发生.它只是静音.查看 Chrome 开发工具的 Networking 选项卡,我只看到 websocket 传出 GET 请求,但没有传入数据包 - 这应该发生吗?如果我强行关闭应用程序,WebSocket 会抛出这个异常:

On execution, the TPCListener successfully accepts the TCPClient and reads the incoming HTTP request. It parses the Key, generates the correct Accept token, but the JS - window native - WebSocket seems to have gone flat out bonkers: it does not answer no matter what it receives. I would expect it throwing an error upon sending a HTTP/1.1 400 Bad Request, but nothing at all happens. It just goes mute. Checking out Chrome Dev Tools' Networking tab, I do only see the websocket outgoing GET request, but no incoming packets - is that supposed to happen? If I forcefully close the application, WebSocket throws this exception:

WebSocket 连接到ws://localhost:42001/websocket"失败:WebSocket 握手期间出错:net::ERR_CONNECTION_RESET.

我在这里错过了什么?提前谢谢大家.

What am I missing here? Thank you all in advance.

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

Also, I'm not using Net.WebSockets because it is available since .NET 4.5, and my application targets systems from Windows 7 to the current build of Windows 10.

推荐答案

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

well... how far does your C# code get? My first bet would be on buffering - you don't flush the writer or stream, so I would expect them to be holding onto data while stuck in the top of the while loop, but frankly it shouldn't be a while loop in the first place - you only get one handshake per socket, not many. You could try adding flushes after the blank line, and you should make sure the Socket itself has buffering disabled (NoDelay = true;) - but: fundamentally this isn't a good way to write a web-socket server. Apart from anything else, the data will cease to be text if the handshake succeeds, so having a TextReader is a very bad thing. Frankly, you should be dealing with raw Socket / byte[] data here, IMO (having implemented this very thing several times).

这篇关于C# WebSocket - 握手期间客户端无响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆