views:

37

answers:

4

I am transferring a file over a NetworkStream and it seems that when the file goes over about 5-10k, the file starts to miss out on data and/or have huge whitespace gaps.

Here is what I have:

private string ReadandSaveFileFromServer(TcpClient clientATF, NetworkStream currentStream, string locationToSave)
{
    int fileSize = 0;
    string fileName = "";
    int bytesRead = 0;

    fileName = ReadStringFromServer(clientATF, currentStream);
    fileSize = ReadIntFromServer(clientATF, currentStream);

    FileStream fs = new FileStream(locationToSave + "\\" + fileName, FileMode.Create);

    byte[] fileSent = new byte[fileSize];

    while (currentStream.DataAvailable)
    {
        if (clientATF.Connected)
        {
            bytesRead = currentStream.Read(fileSent, 0, fileSent.Length);
            fs.Write(fileSent, 0, fileSent.Length);
        }
        else
        {
            break;
        }
    }

    fs.Flush();
    fs.Close();

    return fileName;
}
+2  A: 

No, you've written your buffer code wrong. At a first glance, I would recommend you change to fs.Write(fileSetn, 0, bytesRead) instead.

James Dunne
+2  A: 

Here is the problem: fs.Write(fileSent, 0, fileSent.Length);

you write fileSent.Length bytes to file while you just got bytesRead bytes.

Corrected code:

fs.Write(fileSent, 0, bytesRead);
Xaqron
Another point: if you get disconnected after this line of code: if (clientATF.Connected)Then you get an exception when try to read the stream. I recommend put it in a try/catch
Xaqron
He doesn't have that line of code, and if the peer did an orderly close he doesn't get an exception at all. What are you talking about?
EJP
Checking the peer is connected or not is an async method by design and on return () when he tries to read the stream an exception would raise so any read/write on a stream [bytesRead = currentStream.Read(fileSent, 0, fileSent.Length);] which we are not sure about (on other machines for example) should be used carefully.
Xaqron
Checking whether the peer is connected or not is impossible in TCP whether synchronous or asynchronous, other than by reading from or writing to the socket.
EJP
That's why I recommended putting stream reading in a try/catch because if underlying socket is closed there would be an exception. Anyone who has worked with streams knows that.
Xaqron
the function itself is in a try/catch. I handle a dropped connection. Thanks.
Sean P
A: 

Get rid of the available test and read until you get EOS. That's a misuse of available.

EJP
A: 

Here is the answer. The fs.Write() error was an oversight on my part. Thanks for the help everyone.

  private string ReadandSaveFileFromServer(TcpClient clientATF, NetworkStream currentStream, string locationToSave)
    {
        int fileSize = 0;
        string fileName = "";
        int bytesRead = 0;

        fileName = ReadStringFromServer(clientATF, currentStream);
        fileSize = ReadIntFromServer(clientATF, currentStream);

        FileStream fs = new FileStream(locationToSave + "\\" + fileName, FileMode.Create);

        byte[] fileSent = new byte[fileSize];

        while (fs.Length != fileSize)
        {

                bytesRead = currentStream.Read(fileSent, 0, fileSent.Length);
                fs.Write(fileSent, 0, bytesRead);

        }

        fs.Flush();
        fs.Close();

        return fileName;
    }
Sean P