Hi.
I want to make a program to download files from a remote host.
So what i do is to send throw sockets all the binary information + a string used as end "mystyring".
To check if i have to continue writing the buffer to the file i first convert all to string, so if i find "mystring" it will finish, if not, i reconvert all to bytes and i copy data.
The problem im having is that, .txt files are writed well, but binaris not, it always show error at opening. I ve tried copying a pdf, and when i open it show all the pages, but in blank :S. Also if i check the size of the original file is always some bytes bigger than the copy.

FileStream fs = new FileStream("C:\\Users\\Mauri\\Desktop\\" + item.Name, FileMode.Append, FileAccess.Write);
            BinaryWriter writer = new BinaryWriter(fs);
            bool continua = true;
            while (continua)
            {
                recibido = getSocket(numsock).socketRecv(); // This return the data converted to string.
                words = recibido.Split('|'); //We split "|mystring" to find the end of file.
                foreach (string s in words)
                {
                    if ((String.Compare(s, "mystring") != 0))                        
                        writer.Write(StringToBytes(s)); // Write converted data. 
                    else
                        continua = false; // if we find "mystring", end the action.
                }   
            }
            writer.Close();
            fs.Close();

// Convert string to bytes
public byte[] StringToBytes(String cadena)
        {
            System.Text.ASCIIEncoding codificador = new System.Text.ASCIIEncoding();
            return codificador.GetBytes(cadena);
        }

The strange thing is that .txt files are writed correctly.
Thanks

Dani AI

Generated

Your code is corrupting the file by treating raw bytes as text. Converting arbitrary file data to a .NET string (and using ASCIIEncoding) is not reversible for binary: bytes above 0x7F get replaced, multibyte encodings can expand bytes, and delimiter-splitting on text breaks the original stream. As pointed out, that’s why text files look fine but binaries don’t; and ’s hint about using the length is the right direction.

Reliable fixes (choose one):

  • Use a length-prefixed transfer. Send a fixed-size header with the file length (Int64) then stream exactly that many raw bytes. On the receiver, read the header, then loop reading from the socket until you have received the declared byte count and write those bytes directly to a FileStream — no string conversions.

Example receiver sketch (C#-style pseudocode):

byte[] lenBuf = ReadExact(socket, 8); // 8 bytes in network order
long total = IPAddress.NetworkToHostOrder(BitConverter.ToInt64(lenBuf,0));
using (var fs = File.OpenWrite(destPath)) {
  byte[] buf = new byte[8192];
  long remain = total;
  while (remain > 0) {
    int toRead = (int)Math.Min(buf.Length, remain);
    int got = socket.Receive(buf, 0, toRead, SocketFlags.None);
    if (got <= 0) throw new IOException("connection closed");
    fs.Write(buf, 0, got);
    remain -= got;
  }
}
  • If you cannot change the wire format, make the sender encode the file with Base64 and send ASCII text; decode on receive with Convert.FromBase64String. That adds ~33% overhead but is safe for text channels.

Avoid sentinel strings appended to raw binary. If you must use a delimiter, frame the binary (escape the delimiter or use multipart control messages) and implement boundary searching that preserves overlap between buffers — but framing with length is simpler and robust.

Debug tips: verify sizes and checksums (MD5/SHA256) of both files, handle short reads in a loop, and always write raw byte[] buffers to disk — never go through a string for arbitrary binary.

Recommended Answers

All 4 Replies

I'm also working on something similar to this. I believe your problem is that you're writing a string representation of the data to the file. .txt files contain only text and nothing else. Right click a .txt file and open it with Notepad. It's just text. Now right click an .exe file and open it with Notepad. It's a bunch of garbage. That's the file's raw byte code.

Converting that to a string and writing it to a file is not going to work. You're going to have to write the raw byte code to a file with no changes to it after you receive it.

Use File.WriteAllBytes(Destination, data)

The problem of using writeallbytes is that it will write the "mystring", thats why i ve first converted all to string.

You can't convert a file's byte code to a string and then back to bytes. It will not contain the same data. That's why your copy is smaller than the original; data is lost. I can't explain exactly why this happens but it just does.

I can't think of anything right now that would work with how you have this set up. You have to write the raw data to file without converting it. But I'll try to think of or find something that will work for you. I don't want you to have to rewrite it! I know how that feels. :D

In the meantime could I see your code for 'socketRecv()'?

When/where do you append "mystring" to the end of the received data?

And why do you have to do that anyway? The data returned from the remote host will include the length of the content sent, so you'll know where the "end" of the file is.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.