使用C# Socket发送WebSocket消息

3
我正在查看创建“Hello World” WebSocket示例,并尝试将其调整为通过WebSocket发送在控制台中输入的自定义消息,但我对代码的理解有一些问题。

我的问题是什么是正确的编码方式,以便根据我上面提供的答案正确地发送我的自定义消息。

client.Send(my-own-message);

从你的问题中我所能理解的很少,我猜想你在套接字编程方面几乎没有任何经验。我建议你先从基本的TCP套接字入手,逐步深入学习,不要一开始就涉及这个问题。 - Spencer Ruport
@Meekel 你想要发送什么? 你是想要向网络发送数据吗? 你的客户端是哪个类? - Danpe
@Danpe 我只是想发送一些 JavaScript 代码,然后在 JS 的 onmessage 中对其进行 eval。我曾经看到过一个名为 Waldo 的示例,它是基于 websocketpp 构建的,可以做类似的事情。 - AreYouSure
2
哇,你到底在问什么?这是关于如何使用现有的websocket实现发送消息,还是如何根据websocket规范格式化数据,或者如何从标准输入流中读取数据,或者其他十几个问题之一吗?请尽量将您的问题缩小到只涉及一个问题,并告诉我们相关的背景,不要提其他内容。如果您能够从控制台获取字符串,则删除代码中的“从控制台获取字符串”部分,只展示您对结果字符串的操作,例如: - jalf
@Meekel 谢谢,现在我更清楚你想知道什么了。我尝试发布了一个答案,希望能有所帮助。 :) - jalf
显示剩余5条评论
2个回答

2
你应该真正地看源代码。Websocket规范实际上很容易阅读,它告诉你消息应该如何格式化。
简而言之,假设您已经完成了建立连接的初始握手,这里是Websocket帧应包含的数据:
  • 操作码:一个单字节,如果消息格式为UTF-8文本,则值为0x81,如果消息为二进制数据,则值为0x82(请注意,一些浏览器不支持后者)
  • 长度字段:一个或多个字节,描述消息的长度。第一个字节的最高位必须在客户端发送的消息中设置(它表示负载已屏蔽,这必须在客户端到服务器的消息上执行,并且在服务器到客户端的消息上不能执行)。长度字段可以具有可变长度:如果长度小于126字节,则仅将其编码为单个字节(最高位保留用于指示屏蔽,如前所述)。如果长度小于65KB,则第一个字节的7个可用位取值为126,随后的两个字节包含长度作为16位整数。否则,第一个字节的7位取值为127,随后的8个字节包含长度作为64位整数。
  • 4字节屏蔽密钥,必须为每个消息随机选择
  • 最后,您希望发送的实际消息。这必须使用屏蔽密钥进行屏蔽,只需将每个字节与屏蔽密钥的一个字节进行异或即可(消息的第i个字节应与屏蔽密钥的第i%4个字节一起进行异或)。
这样做,您就创建了一个包含UTF8文本或原始二进制数据的有效websocket帧。正如您所看到的,涉及到一些步骤,但每个步骤都相对简单。(再次请查看我链接的RFC,因为我刚才是凭记忆写的,所以可能有小的不准确之处)

我感谢你的帮助,jalf! :) - AreYouSure

1
首先,Console.Read() 只读取一个字符并返回表示该字符的 int。
如果您想发送消息,可能需要使用返回字符串的 Console.ReadLine()
string msg = Console.ReadLine();
client.Send(GetBytes(msg));

static byte[] GetBytes(string str)
{
    byte[] bytes = new byte[str.Length * sizeof(char)];
    System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
    return bytes;
}

如果编码很重要:

byte[] ascii = System.Text.Encoding.ASCII.GetBytes (msg);
byte[] utf8 = System.Text.Encoding.UTF8.GetBytes (msg);

1
我认为这个问题是关于使消息符合 WebSocket 协议的。因此,它不仅仅是复制数据,而是要在有效载荷前面添加正确的头部并进行遮蔽,以便可以通过 TCP 套接字发送,并由 WebSocket 服务器接收。 :) - jalf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接