C# HTML5 Websocket Server -


i'm trying create c# websocket server don't seem working. have server accepts tcpclient, receives http request client , tries send http response html5 websocket handshake can completed.

i believe there wrong handshake server sends client. read draft (websocket 76 draft) states @ end of handshake response has given 2 keys given. response gets calculated server.

this code:

static void main(string[] args)     {         int port = 8181;         ipaddress localaddr = ipaddress.loopback;          tcplistener server = new tcplistener(localaddr, port);         server.start();          // buffer reading data         byte[] receivedbytes = new byte[256];         string data = null;          // enter listening loop.         while (true)         {             console.writeline("waiting connection...");              // perform blocking call accept requests.             // user server.acceptsocket() here.             tcpclient client = server.accepttcpclient();             console.writeline("connected!\n");              data = null;              // stream object reading , writing             networkstream stream = client.getstream();              int i;               // loop receive data sent client.             while ((i = stream.read(receivedbytes, 0, receivedbytes.length)) != 0)             {                 // translate data bytes ascii string.                 data = system.text.encoding.utf8.getstring(receivedbytes, 0, i);                  console.writeline("received:");                 console.writeline(data);                 byte[] response_token = hashresponse(data);                   string handshake = "http/1.1 101 websocket protocol handshake\r\n"                     + "upgrade: websocket\r\n" + "connection: upgrade\r\n"                     + "sec-websocket-origin: http://localhost\r\n"                     + "sec-websocket-location: ws://localhost:8181/websession\r\n"                     + "\r\n";                  byte[] writtenbytes = encoding.utf8.getbytes(handshake);                  stream.write(writtenbytes, 0, writtenbytes.length);                 stream.write(response_token, 0, response_token.length);                  console.writeline("send:");                 console.writeline(handshake);                  string strhash = encoding.utf8.getstring(response_token);                 console.writeline(strhash);             }                         }     }      static byte[] hashresponse(string receiveddata)     {         string strdel = "\r\n";         char[] delimeter = strdel.tochararray();          string key1 = null;         string key2 = null;         string hash = null;         md5 md5 = md5.create();          string[] lines = receiveddata.split(delimeter);         key1 = lines[10].substring(20);         key2 = lines[12].substring(20);         hash = lines[16];          int64 numberskey1 = convert.toint64(string.join(null, regex.split(key1, "[^\\d]")));         int64 numberskey2 = convert.toint64(string.join(null, regex.split(key2, "[^\\d]")));          int64 numberspaces1 = countspaces(key1);         int64 numberspaces2 = countspaces(key2);          int dividedkey1 = (int) (numberskey1 / numberspaces1);         int dividedkey2 = (int) (numberskey2 / numberspaces2);          byte[] encodedkey1 = encoding.utf8.getbytes(dividedkey1.tostring());         byte[] encodedkey2 = encoding.utf8.getbytes(dividedkey2.tostring());         byte[] encodedhash = encoding.utf8.getbytes(hash);          byte[] combined = encoding.utf8.getbytes(dividedkey1.tostring() + dividedkey2.tostring() + hash);          byte[] responsehash = md5.computehash(combined);          return responsehash;     }      static int countspaces(string key)     {         int counter = 0;         char[] chararray = key.tochararray();          foreach (char c in chararray)         {             if (c.equals(' '))                 counter++;         }          return counter;     } 

the html page (which named test.html) i'm using testing hosted apache webserver runs on computer access browsing (in chrome) http://localhost/test.html

does have clue i'm doing wrong because i'm getting quite desperate.

thanks in advance

dennis

here's sample server wrote illustrating handshake phase in accordance draft-ietf-hybi-thewebsocketprotocol-00:

using system; using system.collections.generic; using system.io; using system.net; using system.net.sockets; using system.security.cryptography; using system.text; using system.text.regularexpressions;  class program {     static void main(string[] args)     {         var listener = new tcplistener(ipaddress.loopback, 8080);         listener.start();         while (true)         {             using (var client = listener.accepttcpclient())             using (var stream = client.getstream())             {                 var headers = new dictionary<string, string>();                 string line = string.empty;                 while ((line = readline(stream)) != string.empty)                 {                     var tokens = line.split(new char[] { ':' }, 2);                     if (!string.isnullorwhitespace(line) && tokens.length > 1)                     {                         headers[tokens[0]] = tokens[1].trim();                     }                 }                  var key = new byte[8];                 stream.read(key, 0, key.length);                  var key1 = headers["sec-websocket-key1"];                 var key2 = headers["sec-websocket-key2"];                  var numberskey1 = convert.toint64(string.join(null, regex.split(key1, "[^\\d]")));                 var numberskey2 = convert.toint64(string.join(null, regex.split(key2, "[^\\d]")));                 var numberspaces1 = countspaces(key1);                 var numberspaces2 = countspaces(key2);                  var part1 = (int)(numberskey1 / numberspaces1);                 var part2 = (int)(numberskey2 / numberspaces2);                  var result = new list<byte>();                 result.addrange(getbigendianbytes(part1));                 result.addrange(getbigendianbytes(part2));                 result.addrange(key);                  var response =                     "http/1.1 101 websocket protocol handshake" + environment.newline +                     "upgrade: websocket" + environment.newline +                     "connection: upgrade" + environment.newline +                     "sec-websocket-origin: " + headers["origin"] + environment.newline +                     "sec-websocket-location: ws://localhost:8080/websession" + environment.newline +                      environment.newline;                  var bufferedresponse = encoding.utf8.getbytes(response);                 stream.write(bufferedresponse, 0, bufferedresponse.length);                 using (var md5 = md5.create())                 {                     var handshake = md5.computehash(result.toarray());                     stream.write(handshake, 0, handshake.length);                 }             }         }     }      static int countspaces(string key)     {         return key.length - key.replace(" ", string.empty).length;     }      static string readline(stream stream)     {         var sb = new stringbuilder();         var buffer = new list<byte>();         while (true)         {             buffer.add((byte)stream.readbyte());             var line = encoding.ascii.getstring(buffer.toarray());             if (line.endswith(environment.newline))             {                 return line.substring(0, line.length - 2);             }         }     }      static byte[] getbigendianbytes(int value)     {         var bytes = 4;         var buffer = new byte[bytes];         int num = bytes - 1;         (int = 0; < bytes; i++)         {             buffer[num - i] = (byte)(value & 0xffl);             value = value >> 8;         }         return buffer;     } } 

and sample client:

<!doctype html public "-//w3c//dtd xhtml 1.0 transitional//en"     "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>     <script type="text/javascript">         var socket = new websocket('ws://localhost:8080/websession');         socket.onopen = function() {             alert('handshake established. may send data now...');         };         socket.onclose = function() {             alert('connection closed');         };     </script> </head> <body> </body> </html> 

Comments