Question

Here is my method for sending data:

    // this method serializes an object and is returned as a string (Base64 encoded)
    public void Send(Packet packetData)
    {
        try
        {
            StreamWriter w = new StreamWriter(cli.GetStream());
            string s = SerializeObject(packetData);
            w.WriteLine(s + "\n");
            w.Flush();
        }
        catch (ObjectDisposedException) { ShutdownClient(-2); }
    }
  • cli is TcpClient object
  • Packet is a serializable object

Here's my receive method:

    private string GetMessage(StreamReader r)
    {
        try
        {
            string s = r.ReadLine();
            s = s.Replace(" ", "");

            // this string is returned and then deserialized
            return s;
        }
        catch (Exception e) { System.Windows.Forms.MessageBox.Show(e.Message); return null; }
    }

When I use this, 50% of the time it works. If it doesn't work, it's because of this: "The input stream is not a valid binary format. The starting contents (in bytes) are: 6D-2E-44-72-61-77-69-6E-67-2E-43-6F-6C-6F-72-0F-00 ..."

I have tried using Encoding.Default.GetString/GetBytes in replacement of Base64, but then I get this: "Binary stream '0' does not contain a valid BinaryHeader. Possible causes are invalid stream or object version change between serialization and deserialization." If I print out the length of this (Default encoded) string, it is 183. But if I print out the actual string, nothing is printed.

How else can I send a byte[] as a string over StreamWriter?

Was it helpful?

Solution

How else can I send a byte[] as a string

Not the way you do it now, the byte[] content will get corrupted when the string is normalized. A string should only ever be used to store Unicode characters. Not every Unicode codepoint is valid.

If using a string is paramount then you should use Convert.ToBase64String() at the transmitter, Convert.FromBase64String() at the receiving end.

Do keep in mind that TCP is entirely capable of transferring binary data. You possibly fell into this hole because TCP implements a stream, it doesn't do anything to help you transmit messages. The simple way to transfer a binary 'message' is to first write the Length of the byte[]. The receiver first read that length, then knows what it should pass to the Read() call to recover the byte[] back from the TCP stream.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top