将数据从网站发送到C#表单应用程序

时间:2019-07-14 19:34:53

标签: javascript c# sockets

我有一个使用webrtc捕获框架的网站。该框架需要通过Internet发送到将处理该框架的Windows窗体应用程序中。

var data = Canvas.toDataURL('image/png');
$.ajax({
    url: 'http://localhost',
    type: 'POST',
    contentType: 'application/octet-stream',
    data: data,
    processData: false
});

因此,我使TcpListerner侦听端口80,并且当连接打开时,此代码将运行:

byte[] bytes = new byte[Server.PackageSize];
int bytesRec = -1;

do
{
    // Get the package
    if (Server.InputUseSSL)
    {
        bytesRec = SslStream.Read(bytes, 0, bytes.Length);
    }
    else
    {
        bytesRec = NetworkStream.Read(bytes, 0, bytes.Length);
    }

    // Clean the array
    byte[] cleanbytes = new byte[bytesRec];
    Buffer.BlockCopy(bytes, 0, cleanbytes, 0, bytesRec);

    var text = System.Text.Encoding.Default.GetString(cleanbytes);
    // OPTIONS / HTTP/1.1
    // Host: localhost
    // Connection: keep-alive
    // Access-Control-Request-Method: POST
    // Origin: https://localhost:44323
    // User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
    // Access-Control-Request-Headers: content-type
    // Accept: */*
    // Accept-Encoding: gzip, deflate, br
    // Accept-Language: nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7

} while (bytesRec != 0 && Socket.Connected && !IsAlreadyStopped && !StopSwitch);

我对OPTIONS http标头有什么反应?

为什么我没有得到文件?

为什么这么难? (我在过去的6个小时里一直在尝试这个,这让我很不高兴)

1 个答案:

答案 0 :(得分:1)

应该使用了websocket:

JavaScript

ChangeConnection: function () {

    if ($("#ServerAddress").val() !== '') {

        try {

            Camera.Connection = new WebSocket('ws://' + $("#ServerAddress").val() + ':80');
            Camera.Connection.onmessage = Camera.DataReceived;
            Camera.Connection.onopen = function (e) {
                Camera.ConnectionOpen = true;
                Camera.Connection.send("Start");
            };
            Camera.Connection.onclose = function (e) {
                Camera.ConnectionOpen = false;
            };

        }
        catch (ex) {

            Log(ex);

        }

    }
},
DataReceived: function (e) {

    var data = e.data;
    Log("Data received:\n" + data);

},
CaputerFrame: function () {

    var context = Camera.Canvas.getContext('2d');
    context.drawImage(Camera.Video, 0, 0, Camera.Width, Camera.Height);

    var data = Camera.Canvas.toDataURL('image/png');
    Camera.Connection.send("Frame: " + data);

    Log("Frame send");

},

C#

    /// <summary>
    /// The thread function that handles data received from client connected to this server
    /// </summary>
    void ReceivePoller()
    {
        // Connect the socket to the remote endpoint. Catch any errors.
        try
        {
            var bytes = new byte[Server.PackageSize];
            var package = new List<byte>();
            var bytesRec = -1;
            var handshakesend = false;
            List<byte> blob = new List<byte>();

            do
            {
                // Get the package
                if (Server.InputUseSSL)
                    bytesRec = SslStream.Read(bytes, 0, bytes.Length);
                else
                    bytesRec = NetworkStream.Read(bytes, 0, bytes.Length);

                // Clean the array
                byte[] cleanbytes = new byte[bytesRec];
                Buffer.BlockCopy(bytes, 0, cleanbytes, 0, bytesRec);

                // Check if handshaken
                if (!handshakesend)
                {
                    var data = System.Text.Encoding.Default.GetString(cleanbytes);

                    if (Server.Debug)
                        Context.Logging.Message(IpAddress + "<-- " + data.Length + " B: " + data);

                    if (new System.Text.RegularExpressions.Regex("^GET").IsMatch(data))
                    {
                        const string eol = "\r\n"; // HTTP/1.1 defines the sequence CR LF as the end-of-line marker

                        var response = "HTTP/1.1 101 Switching Protocols" + eol
                            + "Connection: Upgrade" + eol
                            + "Upgrade: websocket" + 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;
                        Byte[] responseBytes = Encoding.UTF8.GetBytes(response);
                        NetworkStream.Write(responseBytes, 0, responseBytes.Length);

                        if (Server.Debug)
                            Context.Logging.Message(IpAddress + "--> " + response.Length + " B: " + response);

                        handshakesend = true;
                    }
                    else
                    {
                        // Shut it down man!
                        Stop();
                    }
                }
                else
                {
                    blob.AddRange(cleanbytes);

                    if (!NetworkStream.DataAvailable)
                    {
                        // Decode the received data
                        var data = DecodedData(blob.ToArray(), blob.Count);

                        if (Server.Debug)
                            Context.Logging.Message(IpAddress + "<-- " + data.Length + " B: " + data);

                        // Process message
                        Server.ProcessMessage(this, data);

                        // Reset the blob
                        blob.Clear();
                    }
                }

            } while (bytesRec != 0 && Socket.Connected && !IsAlreadyStopped && !StopSwitch);

        }
        catch (System.IO.IOException ex)
        {

        }
        catch (SocketException ex)
        {

        }
        catch (Exception ex)
        {
            // When the connection is lost the waiting thread will be ended with a exception. 
            // We use this to notify the other connection (LAN) that the connection has ended.
            // So there is no need to see this in our error logging.

            if (Server.Debug) Context.Logging.Message(IpAddress + " Client.DataReceive ERROR" + Environment.NewLine + ex.ToString());
        }

        // Stop the client just in case
        Stop();
    }

    /// <summary>
    /// Will decode the received byte array from the websocket
    /// </summary>
    /// <param name="buffer"></param>
    /// <param name="length"></param>
    /// <returns></returns>
    string DecodedData(byte[] buffer, int length)
    {
        byte b = buffer[1];
        int dataLength = 0;
        int totalLength = 0;
        int keyIndex = 0;

        if (b - 128 <= 125)
        {
            dataLength = b - 128;
            keyIndex = 2;
            totalLength = dataLength + 6;
        }

        if (b - 128 == 126)
        {
            dataLength = BitConverter.ToInt16(new byte[] { buffer[3], buffer[2] }, 0);
            keyIndex = 4;
            totalLength = dataLength + 8;
        }

        if (b - 128 == 127)
        {
            dataLength = (int)BitConverter.ToInt64(new byte[] { buffer[9], buffer[8], buffer[7], buffer[6], buffer[5], buffer[4], buffer[3], buffer[2] }, 0);
            keyIndex = 10;
            totalLength = dataLength + 14;
        }

        if (totalLength > length)
            throw new Exception("The buffer length is small than the data length");

        byte[] key = new byte[] { buffer[keyIndex], buffer[keyIndex + 1], buffer[keyIndex + 2], buffer[keyIndex + 3] };

        int dataIndex = keyIndex + 4;
        int count = 0;
        for (int i = dataIndex; i < totalLength; i++)
        {
            buffer[i] = (byte)(buffer[i] ^ key[count % 4]);
            count++;
        }

        return Encoding.ASCII.GetString(buffer, dataIndex, dataLength);
    }

    /// <summary>
    /// Function used by the LAN receive data thread
    /// </summary>
    /// <param name="data">Data to send</param>
    public void SendData(string data)
    {
        try
        {
            var bytes = Encoding.UTF8.GetBytes(data);
            SendData(bytes, bytes.Length);
        }
        catch (Exception ex)
        {
            if (Server.Debug) Context.Logging.Warning(ex);
        }
    }
    /// <summary>
    /// Function used by the LAN receive data thread
    /// </summary>
    /// <param name="bytes">Data to send</param>
    /// <param name="length">Length of the data to send</param>
    public void SendData(byte[] bytes, int length)
    {
        try
        {
            if (!IsAlreadyStopped && !StopSwitch)
            {
                if (Server.InputUseSSL)
                    SslStream.Write(bytes);
                else
                    NetworkStream.Write(bytes, 0, length);

                if (Server.Debug) Context.Logging.Message(IpAddress + "--> " + bytes.Length + " B: " + System.Text.Encoding.Default.GetString(bytes));
            }
        }
        catch (Exception ex)
        {
            if (Server.Debug) Context.Logging.Warning(ex);
        }
    }