1

I have a problem in sending file through webscoket in browser with js to c# server. When I want to save the buffer, if it is a txt file, there is no problem But if it is a photo, for example, the photo will not be opened after saving Where am I going wrong?

private void BeginReceive()
{
    try
    {
        Buffer = new byte[BufferSize];
        Socket.BeginReceive(Buffer, 0, BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), this);
    }
    catch (SocketException ex)
    {
        Console.WriteLine("{0}: {1}", "BeginReceive", ex.Message);
        Close();
    }
    catch (Exception ex)
    {
        Console.WriteLine("{0}: {1}", "BeginReceive", ex.Message);
    }
}

private void ReceiveCallback(IAsyncResult ar)
{
    try
    {
        if (CheckState(ar))
        {
            int bytesRead = Socket.EndReceive(ar);
            Console.WriteLine("{0}: {1}", "bytesRead: ", bytesRead);
            File.WriteAllText(@"c:\01.jpg", Helper.DecodedBytes(Buffer, bytesRead));
        }
    }
    catch (SocketException)
    {
        Close();
    }
    catch (Exception ex)
    {
        Console.WriteLine("{0}: {1}", "ReceiveCallback", ex.Message);
    }
    finally
    {
        if(!Helper.SocketIsDisposed(Socket))  BeginReceive();
    }
}

I think the problem is with the decode function

 public static string DecodedBytes(byte[] buffer, int length)
 {
    if(buffer[0] == 136 && (buffer[1] == 130 || buffer[1] == 128)) throw new System.Net.Sockets.SocketException(10054); //[10054]: Connection reset by peer
    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.UTF8.GetString(buffer, dataIndex, dataLength);
}

and js code:

connect:function(){
        var root = this;
        root.websocket = new WebSocket(root.url);
        root.websocket.binaryType = "arraybuffer";
        root.websocket.onopen = () => root.fireEvent('connect');
        root.websocket.onmessage = (e) => {
            root.fireEvent('receive',JSON.parse(e.data));
        }
        window.addEventListener("beforeunload", function() {
            root.websocket.onclose = function () {}; 
            root.websocket.close();
        });
    },
sendFile:function(){
        var root = this;
        var file = document.getElementById('filename').files[0];
        var loader = new FileReader();
        loader.onload = (e) => {
            var a = e.target.result;
            root.controller.websocket.send(e.target.result);
        }
        loader.readAsText(file)
    },
1
  • Test the encode and decode methods to see if the work properly. Put the encode and decode into a method. Take image and endcode than decode the results and make sure the input and output exactly match. Commented Oct 3, 2022 at 15:41

1 Answer 1

1

Problem solved

JS code changed to:

sendFile:function(){
    var root = this;
    var file = document.getElementById('filename').files[0];
    var loader = new FileReader();
    loader.onload = (e) => {
        var byteArray = new Uint8Array(e.target.result);
        root.controller.websocket.send(byteArray.buffer);
    }
    loader.readAsArrayBuffer(file);
}

and C# code changed to: WriteAllText to WriteAllBytes

File.WriteAllBytes(@"c:\01.jpg", Helper.DecodedBytes(Buffer, bytesRead));

and Encoding.Default.GetString(buffer, dataIndex, dataLength) to buffer.Skip(dataIndex).ToArray()

return buffer.Skip(dataIndex).ToArray();
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.