When I send 127+ characters from chrome websocket, my golang server cannot see more than 126

huangapple go评论71阅读模式
英文:

When I send 127+ characters from chrome websocket, my golang server cannot see more than 126

问题

我正在翻译以下内容:

我正在兴致勃勃地重新发明轮子,并玩弄比特来实现一个简单的服务器。它几乎可以正常工作了,但我不确定这个问题是我的客户端还是我的服务器引起的。下面是我在net.Conn Read函数中传递结果字节数组的部分代码:

func readWsFrame(p []byte) {
    // 处理第一个字节
    b := p[0]
    fmt.Printf("第一个字节:%b\n", b)
    fin := b & 128 // 希望是128,表示fin
    op := b & 15   // 希望是1,表示文本
    fmt.Printf("fin:%d\nop:%d\n", fin, op)
    // 处理第二个字节
    b = p[1]
    fmt.Printf("第二个字节:%b\n", b)
    masked := b & 128 // 表示负载是否经过掩码处理
    length := b & 127 // 负载长度
    fmt.Printf("masked:%d\nlength:%d\n", masked, length)
    // 处理第3到第7个字节(掩码密钥)
    key := p[2:6]
    // 负载
    d := p[6:]
    if length == 126 {
        key = p[4:8]
        d = p[8:]
        fmt.Println("中等长度的密钥")
    } else if length == 127 {
        key = p[10:14]
        d = p[14:]
        fmt.Println("较大长度的密钥")
    } else {
        fmt.Println("较小长度的密钥")
    }
    fmt.Printf("掩码密钥:%b\n", key)
    fmt.Printf("掩码数据:%b\n", d)
    var decoded []byte
    for index := 0; index < int(length); index++ {
        decoded = append(decoded, d[index]^key[index%4])
    }
    fmt.Printf("解码后的数据:%b\n", decoded)
    payload := string(decoded)
    fmt.Println("负载:", payload)
}

客户端代码是我在浏览器的开发控制台中运行的:

var ws = new WebSocket("ws://localhost:16163");
ws.send("a".repeat(125));
ws.send("a".repeat(126));
ws.send("a".repeat(127));
ws.send("a".repeat(400));

我的服务器在处理127个字符之前都符合我的预期。但是,当长度超过126时,我的第二个字节是11111110,而长度是126。我可以看到未经掩码/编码/魔术处理的消息不会超过126个a。

我确信我的Go代码可能不够好,可能有一些明显的问题,但我正在查看比特位本身,我发现在我期望为1的位置上有一个0,请帮助我,谢谢!

--编辑:

我意识到根据我那里的循环,我永远不会看到超过126个字符,但是对于这些更大的消息,我仍然应该在第二个字节的最后一位看到一个1,对吗?

--编辑:

我看到了这个问题:https://stackoverflow.com/questions/18271598/how-to-work-out-payload-size-from-html5-websocket

我想我可能误解了我之前搜索到的所有内容。有人可以确认一下吗?如果长度小于126,则长度为字节与127的按位与。如果长度为126,则长度为下两个字节的值。如果长度为127,则长度为下4个字节的值。

我最初以为如果负载长度为127+,那么长度将为127,哈哈,我错了。所以当长度为126或127时,第二个字节不是实际长度的一部分?我可能会通过测试来确认所有这些,但在周末之前,感谢大家解决了这个问题,这样我就可以完成这个副项目了。

英文:

I'm having a blast reinventing the wheel and playing with bits to implement a simple server. It's almost functional, but I'm not sure if this issue is my client or my server. Here is the function where I pass the resulting byte array from net.Conn Read

func readWsFrame(p []byte) {
// process first byte
b := p[0]
fmt.Printf(&quot;first byte: %b\n&quot;, b)
fin := b &amp; 128 // hopefully 128, for fin
op := b &amp; 15   // hopefully 1, for text
fmt.Printf(&quot;fin: %d\nop: %d\n&quot;, fin, op)
// process second byte
b = p[1]
fmt.Printf(&quot;second byte: %b\n&quot;, b)
masked := b &amp; 128 // whether or not the payload is masked
length := b &amp; 127 // payload length
fmt.Printf(&quot;masked: %d\nlength: %d\n&quot;, masked, length)
// process bytes 3-7 (masking key)
key := p[2:6]
// payload
d := p[6:]
if length == 126 {
key = p[4:8]
d = p[8:]
fmt.Println(&quot;med key&quot;)
} else if length == 127 {
key = p[10:14]
d = p[14:]
fmt.Println(&quot;big key&quot;)
} else {
fmt.Println(&quot;lil key&quot;)
}
fmt.Printf(&quot;masking key: %b\n&quot;, key)
fmt.Printf(&quot;masked data: %b\n&quot;, d)
var decoded []byte
for index := 0; index &lt; int(length); index++ {
decoded = append(decoded, d[index]^key[index%4])
}
fmt.Printf(&quot;unmasked data: %b\n&quot;, decoded)
payload := string(decoded)
fmt.Println(&quot;payload: &quot;, payload)
}

The client code is me having the dev console open right off this web page and running

var ws = new WebSocket(&quot;ws://localhost:16163&quot;);
ws.send(&quot;a&quot;.repeat(125))
ws.send(&quot;a&quot;.repeat(126))
ws.send(&quot;a&quot;.repeat(127))
ws.send(&quot;a&quot;.repeat(400))

My server is doing what I expect until I reach 127 characters. At that point, and every amount over 126, my 2nd byte is 11111110 and the length is 126. I can see the unmasked/encoded/magic message doesn't go beyond 126 a's.

I'm sure my go code is sub-par and there might be something obvious here, but I'm looking at the bits themselves, and I can see a 0 where I am expecting a 1, please help me, thank you!

I saw a similar question about writing messages larger than 126 bytes and how I'll need extra bytes for payload size, but in this case my client is the chrome web browser.

--edit:

I realize that I will never see more than 126 characters based on the loop I have there, but I should still see a 1 in the final bit in the second byte for these larger messages, right?

--edit:

Came across this https://stackoverflow.com/questions/18271598/how-to-work-out-payload-size-from-html5-websocket

I guess I misunderstood everything else I was searching for. Can someone confirm this? If the length is <126, the length is byte & 127. If the length is 126, the length is the value of the next 2 bytes. If the length is 127, the length is the next 4 bytes.

I thought initially that the length would be 127 if it payload length was 127+ hah, oops. So when the length is 126 or 127, the 2nd byte is not part of the actual length? I'll probably confirm all of this with testing, but I thank you all for resolving this issue before the weekend so I can finish this side project.

答案1

得分: 0

代码在读取后续字节中的长度数据后,应该在意识到长度为127或126时更新长度属性。

对于这7个“长度”位,我会稍微不同地解释。它们并不真正表示长度,而是表示编码方式。

如果长度使用64位(8字节)进行编码,则长度指示符为127。

如果长度使用2字节进行编码,则指示符为126。

否则,长度将在指示符本身的7位中进行编码。

例如,长度60可以用这三种方式编码(尽管某些方式使用更多的空间)。

如果你想要阅读一个解码长度的示例,可以参考这里的C Websocket实现

祝你好运!

英文:

The code should update the length property after realizing it's 127 or 126 by reading the length data in the bytes that follow the initial length indicator.

I would consider those 7 "length" bits slightly differently. They don't really indicate length as much as they indicate encoding.

If the length is encoded using 64bits (8 bytes), than the length indicator == 127.

If the length is encoded in 2 bytes, than the indicator == 126.

Otherwise, the length is encoded in the 7 bits of the indicator itself.

For example, the length 60 can be encoded in all three ways (albeit, some use more space).

There's a C Websocket implementation here if you want to read an example decoding of the length.

Good Luck!

huangapple
  • 本文由 发表于 2017年4月28日 08:43:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/43670150.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定