websocket握手问题

2024-04-23

我正在使用 python 实现一个简单的 websocket 服务器。 我使用的握手来自.

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

未捕获的错误:INVALID_STATE_ERR:DOM 异常 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 无法建立连接 到服务器 ws://localhost:8888/。

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

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

Sec-WebSocket-Key1 和 Sec-WebSocket-Key2 字段和 字段后八个字节 服务器使用的随机令牌 最后构造一个16字节的token 的握手来证明它已经 读取客户的握手信息。

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

编辑:如何生成该数字

让我们从 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))

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

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

由密钥产生的两个数字是:

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

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

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

然后我们采用这些字节的 md5 哈希值来获取我们在握手结束时添加的幻数

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

我认为至少是这样的

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

websocket握手问题 的相关文章

  • 管理文件字段当前 url 不正确

    在 Django 管理中 只要有 FileField 编辑页面上就会有一个 当前 框 其中包含指向当前文件的超链接 但是 此链接会附加到当前页面 url 因此会导致 404 因为不存在这样的页面 例如 http 127 0 0 1 8000
  • 如何从数据框的单元格中获取值?

    我构建了一个条件 从我的数据框中提取一行 d2 df df l ext l ext df item item df wn wn df wd 1 现在我想从特定列中获取一个值 val d2 col name 但结果 我得到一个包含一行和一列
  • 有没有任何方法可以使用 openpyxl 获取 .xlsx 工作表中存在的行数和列数?

    有没有任何方法可以使用 openpyxl 获取 xlsx 工作表中存在的行数和列数 在xlrd中 sheet ncols sheet nrows 将给出列数和行数 openpyxl中有这样的方法吗 给定一个变量sheet 可以通过以下方式之
  • 如何在 Python 中仅列出 zip 存档中的文件夹?

    如何仅列出 zip 存档中的文件夹 这将列出存档中的每个文件夹和文件 import zipfile file zipfile ZipFile samples sample zip r for name in file namelist pr
  • Flask SQLAlchemy 与 MyPy - 模型类型错误

    我遇到了以下组合问题flask sqlalchemy and mypy 当我定义一个新的 ORM 对象时 例如 class Foo db Model pass where db是使用创建的数据库SQL炼金术应用于flask app mypy
  • 日期时间的自定义 JavaScriptConverter?

    我有一个对象 它有一个 DateTime 属性 我想通过 AJAX JSON 将该对象从 ashx 处理程序传递回网页 我不想使用第 3 方控件 当我这样做时 new JavaScriptSerializer Serialize DateT
  • Firefox OS 后台服务

    我想构建一个应用程序 用户可以通过它输入一些设置 并且应用程序将启动后台服务来根据这些设置执行一些任务 我只想在模拟器中运行应用程序和后台服务 我知道它需要 认证 模式才能运行后台服务 但我现在不考虑在 Firefox Marketplac
  • JavaScript - 这个这个

    String prototype foo String prototype foo bar function How can you reference the grandparent string console log this par
  • 检查 href 中是否存在 jQuery 中的查询字符串

    我目前有一段 jQuery 用于附加带有一些位置信息的 URL jQuery a attr href function return this href location 123 abc 我的问题是大多数链接都有一个 其中使用上面的 就可以
  • 网页抓取 - 如何识别网页上的主要内容

    给定一个新闻文章网页 来自任何主要新闻来源 例如时报或彭博社 我想识别该页面上的主要文章内容 并丢弃其他杂项元素 例如广告 菜单 侧边栏 用户评论 在大多数主要新闻网站上都可以使用的通用方法是什么 有哪些好的数据挖掘工具或库 最好是基于Py
  • 为什么严格模式下不允许使用八进制数字文字(解决方法是什么?)

    为什么八进制数字文字不允许JavaScript 严格模式 https developer mozilla org en docs Web JavaScript Reference Strict mode 有什么害处呢 use strict
  • CKEditor TypeError:c[a] 在 CodeIgniter 中未定义

    我正在尝试在基于 codeigniter 的网站中安装 CKEditor 并且我已按照本教程进行操作 Codeigniter 教程中的 CKEditor http nukium com developpement php framework
  • 如何在变量名中使用变量

    所以我正在使用这样的 json 变量 opponentInvData item1 它包含项目 1 到 6 我需要动态访问不同的项目并将它们设置为空 itemNum 是我需要访问的特定项目 我正在尝试使用 eval 函数 var itemNu
  • 如何检查摘要周期是否稳定(又名“Angular 完成编译了吗?”)

    tl dr 最初的问题是 如何在每个摘要周期触发回调 但潜在的问题更有趣 因为这回答了两个问题 所以我继续修改了标题 Context 在解决了所有依赖项 nginclude API 调用等之后 我试图控制 Angular 何时完成 HTML
  • 可选链接在 create-react-app 中不起作用

    In a create react app项目 我正在使用 babel plugin proposal optional chaining在我的 babelrc中 但是 我有这个错误 Module parse failed Unexpect
  • 如何让你的精灵在pygame中跳跃

    目前我已经制作了一个平台游戏 可以左右移动我的角色 他从地上开始 关于如何让他跳的任何想法 因为我不明白 目前 如果我按住向上键 我的玩家精灵将连续向上移动 或者如果我按下它 我的玩家精灵将向上移动并保持向上 我想找个办法远离他 让我重新跌
  • 如何使用 Python 将我的 GoPro Hero 4 相机直播连接到 openCV?

    我在尝试从我的新 GoPro Hero 4 相机捕获实时流并使用 openCV 对其进行一些图像处理时遇到麻烦 这是我的试用 创建的窗口上没有显示任何内容 import cv2 import argparse import time imp
  • JS中如何过滤多个字符串? [复制]

    这个问题在这里已经有答案了 我希望能够过滤数组中的多个字符串 类型 例如我想过滤类型meat并输入fruit在下面的数据结构中 我想要实现的是过滤数据对象 const data type meat food hamburger type f
  • Selenium Python 使用代理运行浏览器[重复]

    这个问题在这里已经有答案了 我正在尝试编写一个非常简单的脚本 该脚本从 txt 文件获取代理 不需要身份验证 并用它打开浏览器 然后沿着代理列表循环此操作一定次数 我确实知道如何打开 txt 文件并使用它 我的主要问题是让代理正常工作 我见
  • Javascript:修改原型不会影响现有实例[重复]

    这个问题在这里已经有答案了 我创建了原型的 2 个实例 更改了原型中的函数 更改反映在两个实例中 很棒 但是 当我通过删除该函数来修改原型时 该函数对于现有实例仍然存在 function A this name cool A prototy

随机推荐