1
votes

I'd appreciate some help/direction with a problem I'm having. I'm hoping to develop an application which would provide a stream of my desktop content from a .NET program to a Windows 10 UWP (.NETCore) program.

I've created this application as a normal Windows Form by following this logic:

Client:

  • Bitmap object used to grab desktop.
  • BinaryFormatter to serialize the Bitmap.
  • TCPClient sends the data over TCP.

Server:

  • TCPListener receives the data.
  • Stream is deserialised using BinaryFormatter.
  • Bitmap is presented to a imagebox.

I'd like to recreate the server side of things as a UWP. I've managed to achieve a successful TCP connection using the StreamSocketListener without issue however I don't seem to understand how to replace the BinaryFormatter in UWP. My current approach is to use a DataReader to read in the stream of bytes but I can't seem to grasp the concept to receieveing the full bitmap image so I can reassemble it again. Any tips on this would be appreciated. I've included the Client/Server snippets below:

Client:

private void SendDeskTopImageOverTCP()
{
    BinaryFormatter binFormatter = new BinaryFormatter();
    mainStream = client.GetStream();

    // Get Desktop bitmap and send over TCP Stream.
    binFormatter.Serialize(mainStream, GetDesktopBitmap());
}

Server:

// What do we do when a connection is made? 
private async void OnConnection(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
    // Indicate Connection Received!
    Debug.WriteLine("Connection Received!"); 

    // Data Stream Reader
    DataReader reader = new DataReader(args.Socket.InputStream);

    // Wait until one or more bytes available
    reader.InputStreamOptions = InputStreamOptions.Partial;

    // Load data from the input stream
    await reader.LoadAsync(200);

    while (reader.UnconsumedBufferLength > 0)
    {
        await reader.LoadAsync(200);

        //View byte stream??
        Debug.WriteLine(reader.ReadByte());

    }

My apologies if this is a straight forward problem, I've tried my best to follow the documentation and searched far and wide for similar issue however I've not came across this. So any help would be appreciated.

1
is this still an issue?czifro

1 Answers

1
votes

I would recommend designing a protocol. The protocol would act like an API. For instance, prior to sending the bitmap, you send the size of the bitmap. Like so:

private byte[] GetDesktopAsBytes() 
{
    return serialize(GetDesktopAsBitmap()); // choose some way of getting bytes
}

private void send(byte[] data) 
{
    // this should be a byte array length = sizeof(int)
    var dataSize = System.BitConverter.GetBytes(data.Length)

    // send dataSize first
    // then send data
}

private byte[] receive() 
{
    var dataSizeRaw = /* receive 4 bytes from tcp conn */ ;
    var dataSize = System.BitConverter.ToInt32(dataSizeRaw,0);

    var data = new byte[dataSize];

    // use tcp conn to fill data.

    return data;
}

// send(GetDesktopAsBytes());

This basic protocol allows the two ends to send things of varying sizes and always send/receive whatever in its entirety. With networking, you really need to think about the data you are sending and receiving and how you are going to ensure it gets from A to B in its entirety. The reason I made the protocol analogous to an API is because it acts like a contract. "If I send this data, I should get this as a response". Then when something breaks protocol, you can either allow the connection to persist and hope next time it will follow protocol. Or, you can terminate connection.

Another thing I recommend is having dedicated send and receive methods. In case you need to use the socket for sending something other than bitmap.

Hope this helps!