コード例 #1
0
        // handle a client connection
        private void ClientHandler(TcpClient client)
        {
            Byte[]        bytes;
            NetworkStream stream = client.GetStream();

            WFLogging.Info("Log client connected.");
            // Wait for data to be available
            while (!stream.DataAvailable)
            {
                ;
            }

            bytes = new Byte[client.Available];
            stream.Read(bytes, 0, bytes.Length);

            //translate bytes of request to string
            String data = Encoding.UTF8.GetString(bytes);

            byte[]       response = null;
            const string eol      = "\r\n"; // HTTP/1.1 defines the sequence CR LF as the end-of-line marker

            WFLogging.Debug("GOT:" + bytes.Length.ToString() + ": " + data);

            if (new System.Text.RegularExpressions.Regex("^GET").IsMatch(data))
            {
            }

            string protocol = new System.Text.RegularExpressions.Regex("Sec-WebSocket-Protocol: (.*)").Match(data).Groups[1].Value.Trim();

            Console.WriteLine("Protocol: " + protocol);
            int l = bytes.Length;

            if (bytes[l - 1] == '\n' && bytes[l - 2] == '\r' && bytes[l - 3] == '\n')
            {
                response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + eol
                                                  + "Upgrade: websocket" + eol
                                                  + "Connection: Upgrade" + eol
                                                  + "Sec-WebSocket-Protocol: " + protocol + eol
                                                  + "Sec-WebSocket-Accept: " + Convert.ToBase64String(
                                                      System.Security.Cryptography.SHA1.Create().ComputeHash(
                                                          Encoding.UTF8.GetBytes(
                                                              new System.Text.RegularExpressions.Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
                                                              )
                                                          )
                                                      ) + eol
                                                  + eol);
                stream.Write(response, 0, response.Length);
                stream.Flush();
                WFLogging.Debug(Encoding.ASCII.GetString(response));
            }
            else
            {
                // What do we do here if we don't get a proper header (or complete header)?
                WFLogging.Info("Didn't get a proper header, closing connection");
                client.Close();
                return;
            }

            // Start sending the log.
            //  Only send the most recent 500 lines of data because sending more
            //  here makes the interface unresponse for too long while it processes
            //  it all.
            int start = (WFLogging.EventLogCount > 500) ? (WFLogging.EventLogCount - 500) : 0;

            for (int i = start; i < WFLogging.EventLogCount; i++)
            {
                string[] e = WFLogging.GetEvent(i);
                try {
                    SendMessage(client, e[0] + "\t" + e[1], 0x01);
                } catch {
                    // Sending to client failed for some reason. So abort.
                    client.Close();
                    return;
                }
            }

            // Push the client to the client list
            clients.Add(client);

            // Handle data comming in over the connection. Mainly we want to
            // check for a close connection frame. If we get a close frame
            // then close the connection.
            while (stream.DataAvailable)
            {
                bytes = new Byte[client.Available];
                stream.Read(bytes, 0, bytes.Length);

                // Data from client that needs to be decoded?
                WFLogging.Debug("Got " + bytes.Length.ToString() + " bytes from client to decode");
                if ((bytes[0] & 0x80) == 0x80)
                {
                    int payload_type    = bytes[0] & 0x0f;
                    int payload_size    = bytes[1] & 0x7f;
                    int payload_masking = bytes[1] & 0x80;
                    WFLogging.Debug("type = " + payload_type.ToString() + " mask = " + payload_masking.ToString() + " len = " + payload_size.ToString());
                    if (payload_size < 126)
                    {
                        if (payload_masking == 0x80)
                        {
                            byte[] mask = new byte[4];
                            mask[0] = bytes[2];
                            mask[1] = bytes[3];
                            mask[2] = bytes[4];
                            mask[3] = bytes[5];
                            for (int i = 0; i < payload_size; i++)
                            {
                                bytes[6 + i] = (byte)(bytes[6 + i] ^ mask[i % 4]);
                            }
                            WFLogging.Debug("Payload: " + Encoding.ASCII.GetString(bytes, 6, payload_size));
                        }
                        else
                        {
                            //for (int i = 0; i < payload_size; i++)
                            //   state.buffer[2+i] = (byte)(state.buffer[2+i] ^ 0x10);
                            WFLogging.Debug("Payload: " + Encoding.ASCII.GetString(bytes, 2, payload_size));
                        }
                    }
                    else
                    {
                        WFLogging.Debug("Extended size: " + payload_size.ToString());
                    }

                    switch (payload_type)
                    {
                    case 0x01:      // text payload
                        Console.WriteLine("Got a text payload");
                        break;

                    case 0x02:      // binary payload
                        Console.WriteLine("Got a binary payload");
                        break;

                    case 0x0A:      // Pong
                        break;

                    case 0x09:      // Ping
                        // Send a pong message back
                        Console.WriteLine("Received ping frame, should send a pong");
                        break;

                    case 0x08:      // close connection
                        Console.WriteLine("Received close frame, closing connection");
                        clients.Remove(client);
                        client.Close();
                        return;
                    }
                }
                else
                {
                    WFLogging.Debug("Non Frame: " + Encoding.ASCII.GetString(bytes, 0, bytes.Length));
                }
            }
        }