2

I am trying to send string/text data from browser client to python server and simply print it out. I have followed several examples on the internet, and all are the same: by using javascript

web_socket.send("text to be sent") 

and (python)

data = web_socket.recv(1024)
print data 

they receive what they want, what is clear and nice printout "text to be sent" on server site.

You can find my .html and .py below:

<!DOCTYPE html>

<html lang="en">
<head>
    <title>Test</title>
    <script src="jquery.js"></script>  
    <script type="application/javascript">
        var ws;

        function init() {
            var servermsg = document.getElementById("servermsg");
            ws = new WebSocket("ws://127.0.0.1:9877/");
            ws.onopen = function(){
                servermsg.innerHTML = servermsg.innerHTML + "<br>Server connected";
            };
            ws.onmessage = function(e){
                servermsg.innerHTML = servermsg.innerHTML + "<br><< Recieved data: " + e.data;
            };
            ws.onclose = function(){
                servermsg.innerHTML = servermsg.innerHTML + "<br>Server disconnected";
            };
        }
        function postmsg(){
            var text = document.getElementById("message").value;
            ws.send(text);
            servermsg.innerHTML = servermsg.innerHTML + "<br>>> Data sent: " + text;
        }
        //$(function(){
        //    var text = document.getElementById("message").value;
        //    ws.send(text);
        //    servermsg.innerHTML = servermsg.innerHTML + "<br>Sent: " + text;            
        //});


    </script>
</head>
<body onload="init();">
    <form action="" onSubmit="postmsg();return false;">
        <input type="text" name="message" value="" id="message">
        <input type="submit" name="submit" value="" id="submit">
    </form>
    <div id="servermsg"><h1>Message log:</h1></div>
</body>

</html>

Server:

#!/usr/bin/env python

import socket
import threading
import struct
import hashlib
import base64

PORT = 9877
_address = ""

def create_handshake_resp(handshake):
final_line = ""
lines = handshake.splitlines()
for line in lines:
    parts = line.partition(": ")
    if parts[0] == "Sec-WebSocket-Key":
        key = parts[2]


magic = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'

accept_key = base64.b64encode(hashlib.sha1(key+magic).digest())

return (
    "HTTP/1.1 101 Switching Protocols\r\n"
    "Upgrade: WebSocket\r\n"
    "Connection: Upgrade\r\n"
    "Sec-WebSocket-Accept: " + accept_key + "\r\n\r\n")


def handle(s, addr):
data = s.recv(1024)
response = create_handshake_resp(data)
s.sendto(response, addr)
lock = threading.Lock()
while 1:
    print "Waiting for data from", addr
    data = s.recv(1024)
    print "Done"
    if not data:
        print "No data"
        break

    print 'Data from', addr, ':', data

print 'Client closed:', addr
lock.acquire()
clients.remove(s)
lock.release()
s.close()

def start_server():
print 'STARTING SERVER...'
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(('', PORT))
s.listen(1)
print 'SERVER STARTED'
while 1:
    conn, addr = s.accept()
    print 'NEW CONNECTION ['+str(len(clients))+'], connected by ', addr
    clients.append(conn)
    threading.Thread(target = handle, args = (conn, addr)).start()

clients = []
start_server()

And server printout (when input was like "AA", or "ABC"):

STARTING SERVER...
SERVER STARTED
NEW CONNECTION [0], connected by  ('127.0.0.1', 43877)
Waiting for data from ('127.0.0.1', 43877)
Done
Data from ('127.0.0.1', 43877) : ����w�q
Waiting for data from ('127.0.0.1', 43877)
Done
Data from ('127.0.0.1', 43877) : ��)B�h
Waiting for data from ('127.0.0.1', 43877)
1
  • Is there a complete working example on this, I think it's very cool! ;) Commented Sep 18, 2013 at 6:22

3 Answers 3

1

I'm working on something similar myself. The Websocket protocol mandates that the client sends all its data using a mask. This is why you see 'garbage' - it's the masked text.

https://www.rfc-editor.org/rfc/rfc6455#section-5

"a client MUST mask all frames that it sends to the server"

Read section 5 of the protocol and all will become clear. The browser (ie the client) is just implementing the protocol as it should (when you call ws.send). You need to do your bit.

Note also that when the sever sends data to the client it must NOT mask. But it still has to supply other info before the actual data (type, length etc).

Sign up to request clarification or add additional context in comments.

Comments

0

To send a message from server side to websocket client you need to do as follows:

message = bytearray([0b10000001, len(original_msg)])

for byte in bytearray(original_msg): 
    message.append(byte)

See a stable server to client unidirectional socket library at https://github.com/westial/SingleSocket

Comments

-1

The problem with the junk data was the javascript code sends the masked data and you must unmask it on the server side and the server sendes the unmasked data to client side.To solve this problem see my git-hub page [][1]https://github.com/mohanbe/web-chat

1 Comment

From review: Links are good but not without a brief about important points. If the link dies then the answer becomes obsolete. Please see stackoverflow.com/help/how-to-answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.