问题描述
限时送ChatGPT账号..我正在尝试为根据浏览器输入进行交互的应用程序编写 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屋!
更多推荐
[db:关键词]
发布评论