编写一个WebSocket服务器

3
我想写一个WebSocket服务器,使用Java和C++两种语言,但目前遇到了困难。在Java中,我使用java.net.ServerSocket / java.net.Socket建立连接,并成功完成握手,但是WebSocket发送到Java服务器的数据并不完全符合我的期望。
当我像这样从JavaScript发送消息时:
var count = 0;
function loop(){
    websocket.send("loop: " + count + "\n");
    count++;

    setTimeout(loop, 100);
}

Java服务器接收到这个信息,每隔一段时间会有换行符,但并不是每次调用websocket.send()都会有换行符。
Java服务器使用BufferedReader.readLine()从套接字中检索值。
BufferedReader socketReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line =socketReader.readLine();

这对于握手来说很好用,所有握手数据都是可读的,但在握手完成后它不起作用。
握手后的数据是否以某种方式加密?我该如何阅读它?
编辑:
程序文件: SocketConnectTest.html ServerTest.java ClientSessionTest.java ResponseGenerator.java output 只需运行ServerTest.java,然后打开SocketConnectTest.html。 ClientSessionTest.initClientListener()处理来自客户端的消息。 解决方案:请参见下面pimvdbs的帖子以及他在如何在WebSockets hybi 08+中(de)构建数据框架?中的答案。

你可以尝试使用telnet连接到你的服务器吗?这将允许你输入纯文本并查看发送和响应的内容(你甚至可以在HTTP服务器上这样做 ;))。 - Peter Lawrey
它可以被压缩;你的 accept-encoding 头信息中包括 gzip 吗?如果是,请移除它并重试。 - trojanfoe
@trojanfoe 我尝试过移除gzip并将其替换为identity,但都没有帮助。 - Markus
1个回答

4

Web sockets传输的数据是原始数据,不是字符串编码数据。

建议不要在传入数据周围包装BufferedReader,因为数据包使用0x00字节进行分帧。你看到的疯狂字符是Java无法理解数据所在编码的结果。

您需要负责将数据拆分成字符和控制部分。一旦将数据拆分为适当的区域,就可以将数据解码为字符串。


我现在尝试使用socket.getInputStream().read(buff)来读取它。每次read()检索到一个字节数组时,前两个字节是-127和-123。然而,即使我始终发送相同的消息,随后的字节似乎是随机的。 - Markus
我们可能需要更详细地了解您的发送方式和消息内容。例如,当您发送时,是否正确地包装了数据? - Jeff Foster
我已经将源代码添加到初始帖子中。 消息是否应该以某种方式进行包装?我看过的教程总是使用send()发送原始字符串,所以我也打算这样开始,并在发送成功后制定自己的应用程序协议。 - Markus
3
数据被编码,密钥是随机的,编码数据也是随机的(结果如此)。前两个字节包含了一些头信息和数据长度,这些你不一定需要。你需要使用规范中定义的算法,用密钥(掩码)字节解码数据字节(我之前在https://dev59.com/nVrUa4cB1Zd3GeqPhjMh#7045885发布了一些伪代码)。 - pimvdb
@pimvdb 希望我能给你的答案点赞多次。太完美了,谢谢! 而且我还学到了Java 7中有二进制字面值,比如0b1000_000。一天的好开始。 - Markus

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