This is the problem:
string received = Encoding.UTF8.GetString(obj.buffer);
Why are you doing this? It's not text. You should be writing a byte array to the file, not a string.
Additionally, you should be using the return value of EndReceive
to know how much data you've read:
int bytesRead = obj.socket.EndReceive(ar);
fileStream.Write(obj.buffer, 0, bytesRead);
(fileStream
should be an actual stream, not a TextWriter
.)
This will work for text files as well - if you treat text as binary, you end up with the same content at the other end, which you can still read as text. If you treat binary data as text, you end up with a mess of corrupted data...