Websocket server, client cannot acknowledge

I am testing the latest version of Chrome (website version 13).

Here my simple client page is at http://127.0.0.1/folder/default.aspx :

 <script type="text/javascript"> var socket = new WebSocket('ws://localhost:8181/websession'); socket.onopen = function () { alert('handshake successfully established. May send data now...'); }; socket.onclose = function () { alert('connection closed'); }; socket.onmessage = function(msg) { alert(msg); }; </script> 

And here is my listener (C #)

 var listener = new TcpListener(IPAddress.Loopback, 8181); listener.Start(); while (true) { Console.WriteLine("Listening..."); using (var client = listener.AcceptTcpClient()) using (var stream = client.GetStream()) using (var reader = new StreamReader(stream)) using (var writer = new StreamWriter(stream)) { writer.WriteLine("HTTP/1.1 101 Web Socket Protocol Handshake"); writer.WriteLine("Upgrade: WebSocket"); writer.WriteLine("Connection: Upgrade"); writer.WriteLine("WebSocket-Origin: http://127.0.0.1"); writer.WriteLine("WebSocket-Location: ws://localhost:8181/websession"); writer.WriteLine(""); } Console.WriteLine("Finished"); } 

When I start the server and then load the client page, it only says "connection closed" .

Can someone tell me how to properly execute this handshake? As far as I can tell from the documentation and the previous questions, the answer that I send back to the client looks correct.

+4
source share
3 answers

Based on your code, this should work (at least with chrome)

 var listener = new TcpListener(IPAddress.Loopback, 8181); listener.Start(); while (true) { Console.WriteLine("Listening..."); using (var client = listener.AcceptTcpClient()) using (var stream = client.GetStream()) using (var reader = new StreamReader(stream)) using (var writer = new StreamWriter(stream)) { string line = null, key = "", responseKey = ""; string MAGIC_STRING = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; while (line != "") { line = reader.ReadLine(); if (line.StartsWith("Sec-WebSocket-Key:")) { key = line.Split(':')[1].Trim(); } } if (key != "") { key += MAGIC_STRING; using (var sha1 = SHA1.Create()) { responseKey = Convert.ToBase64String(sha1.ComputeHash(Encoding.ASCII.GetBytes(key))); } } // send handshake to the client writer.WriteLine("HTTP/1.1 101 Web Socket Protocol Handshake"); writer.WriteLine("Upgrade: WebSocket"); writer.WriteLine("Connection: Upgrade"); writer.WriteLine("WebSocket-Origin: http://127.0.0.1"); writer.WriteLine("WebSocket-Location: ws://localhost:8181/websession"); if (!String.IsNullOrEmpty(responseKey)) writer.WriteLine("Sec-WebSocket-Accept: " + responseKey); writer.WriteLine(""); writer.Flush(); SendString(stream, "This code works!!!!"); SendString(stream, "This code also works!!!! ".PadRight(300, '.') + "\r\nEND"); } Console.WriteLine("Finished"); } void SendString(Stream s, string str) { var buf = Encoding.UTF8.GetBytes(str); int frameSize = 64; var parts = buf.Select((b, i) => new { b, i }) .GroupBy(x => xi / (frameSize - 1)) .Select(x => x.Select(y => yb).ToArray()) .ToList(); for (int i = 0; i < parts.Count; i++ ) { byte cmd = 0; if (i == 0) cmd |= 1; if (i == parts.Count - 1) cmd |= 0x80; s.WriteByte(cmd); s.WriteByte((byte)parts[i].Length); s.Write(parts[i], 0, parts[i].Length); } s.Flush(); } 

PS: use

 socket.onmessage = function(msg) { alert(msg.data); }; 

to view the contents of a message sent by the server.

+3
source

You have not calculated a security hash. The client sends you a number, and in the specifier there is another number encoded in the code. You need to combine them according to the instructions in the specification and return them as a header.

This demonstrates that your server is actually a web socket server.

See RFC6455

Please note that you might also consider whether to implement Hixie 76 in addition to the RFC.

+2
source

StreamReader and StreamWriter on dispose close the underlying stream (NetworkStream). The client page only says: "connection closed"

+1
source

Source: https://habr.com/ru/post/1447788/


All Articles