gpt4 book ai didi

javascript - websocket握手问题

转载 作者:太空狗 更新时间:2023-10-29 21:47:54 24 4
gpt4 key购买 nike

我正在使用 python 实现一个简单的 websocket 服务器。我使用的握手来自 http://en.wikipedia.org/w/index.php?title=WebSockets&oldid=372387414 .

握手本身似乎有效,但是当我点击发送时,我收到一个 javascript 错误:

Uncaught Error: INVALID_STATE_ERR: DOM Exception 11

这是 html:

<!doctype html>
<html>
<head>
<title>ws_json</title>

</head>
<body onload="handleLoad();" onunload="handleUnload();">
<input type="text" id='input' />
<input type="button" value="submit" onclick="handleSubmit()" />
<div id="display"></div>

<script type="text/javascript">
function showmsg(str){
display = document.getElementById("display");
display.innerHTML += "<p>" + str + "</p>";
}

function send(str){
ws.send(str.length);
ws.send(str);
}

function handleSubmit(){
input = document.getElementById('input');
send(input.value);
input.focus();
input.value = '';
}

function handleLoad(){
ws = new WebSocket("ws://localhost:8888/");
ws.onopen = function(){
showmsg("websocket opened.");
}

ws.onclose = function(){
showmsg("websocket closed.");
}
}

function handleUnload(){
ws.close();
}
</script>
</body>
</html>

这是 python 代码:

import socket
import threading
import json

PORT = 8888
LOCATION = "localhost:8888"

def handler(s):

print " in handler "

ip, _ = s.getpeername()
print "New connection from %s" % ip
request = s.recv(1024)

print "\n%s\n" % request
print s.getpeername()

# send response
response = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
response += "Upgrade: WebSocket\r\n"
response += "Connection: Upgrade\r\n"
try:
peername = s.getpeername()
response += "Sec-WebSocket-Origin: http://%s\r\n" % peername[0] # % request[request.index("Origin: ")+8:-4]
except ValueError:
print "Bad Request"
raise socket.error
response += "Sec-WebSocket-Location: ws://%s\r\n" % LOCATION
response += "Sec-WebSocket-Protocol: sample"
response = response.strip() + "\r\n\r\n"

print response
s.send(response)

while True:
length = s.recv(1)
print length
if not length:
break
length = int(length)
print "Length: %i" % length
data = s.recv(length)
print "Received: %s" % data
print ""

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('localhost', PORT))
s.listen(5)

print "server is running..."
while True:
sock, addr = s.accept()
threading.Thread(target=handler, args=(sock, )).start()

有谁知道我在这里做错了什么?

最佳答案

我在 Firefox 4 上测试了您的代码并在点击发送时遇到了同样的错误,但是在此之前我得到了

Firefox can't establish a connection to the server at ws://localhost:8888/.

这可能就是 WebSocket 对象被销毁的原因。我怀疑您的握手响应缺少某些内容,因此 Firefox 正在关闭套接字。

来自维基百科关于 Websockets 的文章:

The Sec-WebSocket-Key1 and Sec-WebSocket-Key2 fields and the eight bytes after the fields are random tokens which the server uses to construct a 16 byte token at the end of its handshake to prove that it has read the client's handshake.

你的服务器的响应底部没有这个特殊数字,所以我认为我们需要弄清楚如何生成它,并包含它。

编辑:如何生成该数字

让我们从 key1、key2 和握手结束时的 8 个字节开始

key1 = "18x 6]8vM;54 *(5:  {   U1]8  z [  8"
key2 = "1_ tx7X d < nw 334J702) 7]o}` 0"
end8 = "Tm[K T2u"

我们通过忽略不是数字 0-9 的每个字符来为每个键创建一个数字。在 Python 中:

def numFromKey(key):
return int(filter(lambda c: c in map(str,range(10)),key))

接下来我们将该数字除以原始 key 字符串中的空格数,因此这是一个计算字符串中空格的函数。

def spacesIn(key):
return len(filter(lambda c: c==' ',key))

由键产生的两个数字是:

pkey1 = numFromKey(key1)/spacesIn(key1)
pkey2 = numFromKey(key2)/spacesIn(key2)

现在我们需要连接 pkey1、pkey2 和 end8 的字节。处理后的 key 需要表示为 32 位 Big-Endian 数字。

from struct import pack
catstring = pack('>L',pkey1) + pack('>L',pkey2) + end8

然后我们采用这些字节的 md5 哈希值来获得我们在握手结束时附加的魔数(Magic Number)

import md5
magic = md5.new(catstring).digest()

至少我认为这是可行的

关于javascript - websocket握手问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3220547/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com