Sending / receiving WebSocket message over Python socket / WebSocket Client

后端 未结 2 1981
予麋鹿
予麋鹿 2021-02-04 17:54

I wrote a simple WebSocket client. I used the code I found on SO, here: How can I send and receive WebSocket messages on the server side?.

I\'m using Python 2.7

2条回答
  •  醉话见心
    2021-02-04 18:32

    I have hacked your code into something that at least sends a reply and receives an answer, by changing the encoding to use chr() to insert byte strings rather than decimals to the header. The decoding I have left alone but the other answer here has a solution for that.
    The real guts of this is detailed here https://www.rfc-editor.org/rfc/rfc6455.txt
    which details exactly what it is that you have to do

    #!/usr/bin/env python
    import socket
    def encode_text_msg_websocket(data):
        bytesFormatted = []
        bytesFormatted.append(chr(129))
        bytesRaw = data.encode()
        bytesLength = len(bytesRaw)
        if bytesLength <= 125:
            bytesFormatted.append(chr(bytesLength))
        elif 126 <= bytesLength <= 65535:
            bytesFormatted.append(chr(126))
            bytesFormatted.append((chr(bytesLength >> 8)) & 255)
            bytesFormatted.append(chr(bytesLength) & 255)
        else:
            bytesFormatted.append(chr(127))
            bytesFormatted.append(chr((bytesLength >> 56)) & 255)
            bytesFormatted.append(chr((bytesLength >> 48)) & 255)
            bytesFormatted.append(chr((bytesLength >> 40)) & 255)
            bytesFormatted.append(chr((bytesLength >> 32)) & 255)
            bytesFormatted.append(chr((bytesLength >> 24)) & 255)
            bytesFormatted.append(chr((bytesLength >> 16)) & 255)
            bytesFormatted.append(chr((bytesLength >> 8)) & 255)
            bytesFormatted.append(chr(bytesLength) & 255)
        send_str = ""
        for i in bytesFormatted:
            send_str+=i
        send_str += bytesRaw
        return send_str
    
    # connect 
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.settimeout(5.0)
    try:
        sock.connect((socket.gethostbyname('ws.websocket.org'), 80))
    except:
        print "Connection failed"
    handshake = '\
    GET /echo HTTP/1.1\r\n\
    Host: echo.websocket.org\r\n\
    Upgrade: websocket\r\n\
    Connection: Upgrade\r\n\
    Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\
    Origin: http://example.com\r\n\
    WebSocket-Protocol: echo\r\n\
    Sec-WebSocket-Version: 13\r\n\r\n\
    '
    sock.send(bytes(handshake))
    data = sock.recv(1024).decode('UTF-8')
    print data
    
    # send test msg
    msg = encode_text_msg_websocket('Now is the winter of our discontent, made glorious Summer by this son of York')
    print "Sent: ",repr(msg)
    sock.sendall(bytes(msg))
    # receive it back
    response = sock.recv(1024)
    #decode not sorted so ignore the first 2 bytes
    print "\nReceived: ", response[2:].decode()
    sock.close()
    

    Result:

    HTTP/1.1 101 Web Socket Protocol Handshake
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Headers: content-type
    Access-Control-Allow-Headers: authorization
    Access-Control-Allow-Headers: x-websocket-extensions
    Access-Control-Allow-Headers: x-websocket-version
    Access-Control-Allow-Headers: x-websocket-protocol
    Access-Control-Allow-Origin: http://example.com
    Connection: Upgrade
    Date: Mon, 08 May 2017 15:08:33 GMT
    Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
    Server: Kaazing Gateway
    Upgrade: websocket
    
    
    Sent:  '\x81MNow is the winter of our discontent, made glorious Summer by this son of York'
    
    Received:  Now is the winter of our discontent, made glorious Summer by this son of York
    

    I should note here, that this is going to be a pig to code without pulling in some extra libraries, as @gushitong has done.

提交回复
热议问题