2

こんにちは、私はウェブソケットをテストしてきましたが、これまでのところすべて接続されています。しかし、サーバーへの送信とデータを開始すると、奇妙な文字がたくさん表示されます。

(これらのコードは検索から取得しました)

サーバーは次のとおりです。

import socket
import re
from base64 import b64encode
from hashlib import sha1

websocket_answer = (
    'HTTP/1.1 101 Switching Protocols',
    'Upgrade: websocket',
    'Connection: Upgrade',
    'Sec-WebSocket-Accept: {key}\r\n\r\n',
)

GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 8999))
s.listen(1)

client, address = s.accept()
text = client.recv(1024)
print "RECV----------------------------------"
print text

key = (re.search('Sec-WebSocket-Key:\s+(.*?)[\n\r]+', text)
    .groups()[0]
    .strip())

response_key = b64encode(sha1(key + GUID).digest())
response = '\r\n'.join(websocket_answer).format(key=response_key)

print "SEND----------------------------------"
print response
client.send(response)

while 1:
    try :
        print "SEND----------------------------------"
        client.sendall('hello from server')
        print "RECV----------------------------------"
        print client.recv(1024)
    except :
        print "except"
        break

クライアントは次のとおりです。

<!DOCTYPE html>
<html lang="en">
<head>
  <title>WebSocket Echo Client</title>
  <meta charset="UTF-8" />
  <script>
    "use strict";
    // Initialize everything when the window finishes loading
    window.addEventListener("load", function(event) {
      var status = document.getElementById("status");
      var url = document.getElementById("url");
      var open = document.getElementById("open");
      var close = document.getElementById("close");
      var send = document.getElementById("send");
      var text = document.getElementById("text");
      var message = document.getElementById("message");
      var socket;

      status.textContent = "Not Connected";
      url.value = "ws://localhost:8999";
      close.disabled = true;
      send.disabled = true;

      // Create a new connection when the Connect button is clicked
      open.addEventListener("click", function(event) {
        open.disabled = true;
        socket = new WebSocket(url.value, "echo-protocol");

        socket.addEventListener("open", function(event) {
          close.disabled = false;
          send.disabled = false;
          status.textContent = "Connected";
        });

        // Display messages received from the server
        socket.addEventListener("message", function(event) {
          message.textContent = "Server Says: " + event.data;
        });

        // Display any errors that occur
        socket.addEventListener("error", function(event) {
          message.textContent = "Error: " + event;
        });

        socket.addEventListener("close", function(event) {
          open.disabled = false;
          status.textContent = "Not Connected";
        });
      });

      // Close the connection when the Disconnect button is clicked
      close.addEventListener("click", function(event) {
        close.disabled = true;
        send.disabled = true;
        message.textContent = "";
        socket.close();
      });

      // Send text to the server when the Send button is clicked
      send.addEventListener("click", function(event) {
        socket.send(text.value);
        text.value = "";
      });
    });
  </script>
</head>
<body>
  Status: <span id="status"></span><br />
  URL: <input id="url" /><br />
  <input id="open" type="button" value="Connect" />&nbsp;
  <input id="close" type="button" value="Disconnect" /><br />
  <input id="send" type="button" value="Send" />&nbsp;
  <input id="text" /><br />
  <span id="message"></span>
</body>
</html>

そして、接続ボタンを押すと、次のようになります。

RECV----------------------------------
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: localhost:8999
Origin: null
Sec-WebSocket-Protocol: echo-protocol
Sec-WebSocket-Key: v6Fu1rJURofc7iIPbeaw0Q==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
Cookie: BG_PREFS=searches_includeapocrypha@no&fontsize@medium&language@en&default_version_display@all&default_version@SND&default_
version_overrides@no&quicksearch_search@&pslookup_language1@en&pslookup_language2@&pslookup_language3@&pslookup_language4@&pslooku
p_language5@&pslookup_showmoresearches@closed&pslookup_showversions@open&pslookup_showmoreversions@closed&pslookup_showoptions@ope
n&pslookup_showfootnotes@yes&pslookup_showxrefs@no&pslookup_showwoj@no&pslookup_showversenums@yes&pslookup_showheadings@yes&pslook
up_showindent@no&pslookup_multilayout@columns&pslookup_multisort@passage&pslookup_embed-versenum@true&pslookup_embed-xref@false&ps
lookup_embed-footnote@false&pslookup_embed-heading@false&keysearch_search@&keysearch_language1@en&keysearch_language@en&
SEND----------------------------------
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Protocol: echo-protocol
Sec-WebSocket-Accept: qVkmFtRs1w8OUwZSe5nMpTWNxbI=


SEND----------------------------------
RECV----------------------------------
keysearch_bookset@&keysearch_spanbegin@1&keysearch_spanend@73&keysearch_limit@none&keysearch_startnumber@1&keysearch_searchtype@al
l&keysearch_showversions@open&keysearch_showmoreversions@closed&keysearch_showoptions@open&keysearch_displayas@long&keysearch_resu
ltspp@25&keysearch_sort@bookorder&keysearch_wholewordsonly@no&commentary_source@1&topindex_source@1&topindex_search@&topindex_sear
ch_type@any&topindex_resultspp@25&audio_source@3&audio_book@&audio_chapter@&dict_source@1&dict_search@&dict_search_type@any&pslook
up_search@>>>>&pslookup_version@NIV>>>>&undefined&keysearch_version@31>>>>; CoreID6=83844698672113373932637&ci=90320803; __atuvc=2
|20

握手は大丈夫そうで、繋がりました。そして、クライアントからテキスト「テスト」を送信すると、これが得られます。

üäQk╩¼%♫╣╪

これは文字エンコーディングと関係がありますか? サーバーに送信した「テスト」文字列を取得できません。また、クライアント側でも何も得られませんでした。

注: Chrome 19 でクライアントをテストしました。

4

2 に答える 2

2

RFC によると、クライアントはテキスト データを送信せず、バイナリ フレームを送信します。

于 2012-06-22T09:37:20.933 に答える
1

WebSockets はフレーム化されたプロトコルです。raw ソケットと同様の遅延がありますが、データはネットワーク上で raw で送信されません。

  • ヘッダー: フレームの先頭に 2 バイトのヘッダーがあります。ペイロードがそれぞれ 125 バイトまたは 65535 バイトより長い場合、これは 4 バイトまたは 10 バイトのヘッダーになることもあります。

  • Binary or Text : ヘッダーには、データがバイナリかテキストかも示されます。あなたの場合、データはテキストです。バイナリ データを送信するには、Javascript から ArrayBuffer または Blob を送信する必要があります。文字列を送信すると、データはテキストになります。サーバーがバイナリ フレームを送信する場合、onmessage イベントは、WebSocket.binaryType フィールドの設定に応じて、blob または arraybuffer を受け取ります。

  • マスキング: クライアント (ブラウザ) からサーバーへのすべてのデータをマスキングする必要があります。これは、キャッシング仲介者の不正行為に関する理論上の懸念に対処するためのものです。サーバーからクライアントへのデータをマスクしてはなりません。ヘッダーには、ペイロードがマスクされているかどうかを示すビットがあります。マスクされている場合、ヘッダーの後の最初の 4 バイトがマスクです。これは、マスキングを解除するために、実行中の XOR としてペイロード データに適用されます。

あなたの例では、テキスト文字列「test」を送信しました。サーバーは、2 バイトのヘッダー、4 バイトのマスク、4 バイトのマスクされたペイロードの 10 バイトのデータを受信しました。

フレーミングの仕組みとヘッダー内のフィールドのビットレベルの内訳の図については、IETF 6455 WebSocket プロトコル仕様のセクション 5.2 を参照してください。

于 2012-06-22T13:44:42.237 に答える