1 | using System;
|
2 | using System.Net.Sockets;
|
3 | using System.Net;
|
4 | using System.Security.Cryptography;
|
5 | using System.Threading;
|
6 |
|
7 | namespace ConsoleApplication1
|
8 | {
|
9 | class Program
|
10 | {
|
11 | static Socket serverSocket = new Socket(AddressFamily.InterNetwork,
|
12 | SocketType.Stream, ProtocolType.IP);
|
13 | static private string guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
14 |
|
15 | static void Main(string[] args)
|
16 | {
|
17 | serverSocket.Bind(new IPEndPoint(IPAddress.Any, 8080));
|
18 | serverSocket.Listen(128);
|
19 | serverSocket.BeginAccept(null, 0, OnAccept, null);
|
20 | Console.Read();
|
21 | }
|
22 |
|
23 | private static void OnAccept(IAsyncResult result)
|
24 | {
|
25 | byte[] buffer = new byte[1024];
|
26 | try
|
27 | {
|
28 | Socket client = null;
|
29 | string headerResponse = "";
|
30 | if (serverSocket != null && serverSocket.IsBound)
|
31 | {
|
32 | client = serverSocket.EndAccept(result);
|
33 | var i = client.Receive(buffer);
|
34 | headerResponse = (System.Text.Encoding.UTF8.GetString(buffer)).Substring(0,i);
|
35 | // write received data to the console
|
36 | Console.WriteLine(headerResponse);
|
37 |
|
38 | }
|
39 | if (client != null)
|
40 | {
|
41 | /* Handshaking and managing ClientSocket */
|
42 |
|
43 | var key = headerResponse.Replace("ey:", "`")
|
44 | .Split('`')[1] // dGhlIHNhbXBsZSBub25jZQ== \r\n .......
|
45 | .Replace("\r", "").Split('\n')[0] // dGhlIHNhbXBsZSBub25jZQ==
|
46 | .Trim();
|
47 |
|
48 | // key should now equal dGhlIHNhbXBsZSBub25jZQ==
|
49 | var test1 = AcceptKey(ref key);
|
50 |
|
51 | var newLine = "\r\n";
|
52 |
|
53 | var response = "HTTP/1.1 101 Switching Protocols" + newLine
|
54 | + "Upgrade: websocket" + newLine
|
55 | + "Connection: Upgrade" + newLine
|
56 | + "Sec-WebSocket-Accept: " + test1 + newLine + newLine
|
57 | //+ "Sec-WebSocket-Protocol: chat, superchat" + newLine
|
58 | //+ "Sec-WebSocket-Version: 13" + newLine
|
59 | ;
|
60 |
|
61 | // which one should I use? none of them fires the onopen method
|
62 | client.Send(System.Text.Encoding.UTF8.GetBytes(response));
|
63 |
|
64 | var i = client.Receive(buffer); // wait for client to send a message
|
65 |
|
66 | // once the message is received decode it in different formats
|
67 | Console.WriteLine(Convert.ToBase64String(buffer).Substring(0, i));
|
68 |
|
69 | Console.WriteLine("\n\nPress enter to send data to client");
|
70 | Console.Read();
|
71 |
|
72 | var subA = SubArray<byte>(buffer, 0, i);
|
73 | client.Send(subA);
|
74 | Thread.Sleep(10000);//wait for message to be send
|
75 |
|
76 |
|
77 | }
|
78 | }
|
79 | catch (SocketException exception)
|
80 | {
|
81 | throw exception;
|
82 | }
|
83 | finally
|
84 | {
|
85 | if (serverSocket != null && serverSocket.IsBound)
|
86 | {
|
87 | serverSocket.BeginAccept(null, 0, OnAccept, null);
|
88 | }
|
89 | }
|
90 | }
|
91 |
|
92 | public static T[] SubArray<T>(T[] data, int index, int length)
|
93 | {
|
94 | T[] result = new T[length];
|
95 | Array.Copy(data, index, result, 0, length);
|
96 | return result;
|
97 | }
|
98 |
|
99 | private static string AcceptKey(ref string key)
|
100 | {
|
101 | string longKey = key + guid;
|
102 | byte[] hashBytes = ComputeHash(longKey);
|
103 | return Convert.ToBase64String(hashBytes);
|
104 | }
|
105 |
|
106 | static SHA1 sha1 = SHA1CryptoServiceProvider.Create();
|
107 | private static byte[] ComputeHash(string str)
|
108 | {
|
109 | return sha1.ComputeHash(System.Text.Encoding.ASCII.GetBytes(str));
|
110 | }
|
111 | }
|
112 | }
|