Sent file has some corrupted data TCP sockets .. h

2019-09-08 07:26发布

I have problem with my transfer files application .. everything looks great and works the way it should be .. but then I discovered that some pieces of the sent file is corrupted.
Like when I send a video file (.MP4) it sent successfully but when I play it some frames of it got corrupted like in the snapshot picture .. I played the source Mp4 file and the picture was so perfect and never looked like in that snapshot picture.
So here's my code .. I'm confused now about using fs.Seek .. someone told me it doesn't make the new file the same as the source file.

I'm using SOCKETS TCP .. (.Net 4.0)

enter image description here

Send method (CLIENT):

FileStream fs;
long sum;
long fileSize;
byte[] data = null;
NetworkStream network; 
const int packetSize = 1024*8;

private void SendFile(string srcPath, string destPath)
    {
        string dest = Path.Combine(destPath, Path.GetFileName(srcPath));
        using (fs = new FileStream(srcPath, FileMode.Open, FileAccess.Read))
        {
            try
            {
                sum = 0;
                int count = 0;
                data = new byte[packetSize];
                //send the destination path and the file size to SERVER.
                SendCommand("receive<" + dest + "<" + fs.Length.ToString());
                while (sum < fileSize)
                {
                    if (fileSize - sum < packetSize)
                    {
                        count = fs.Read(data, 0, Convert.ToInt32(fileSize - sum));
                        network.Write(data, 0, Convert.ToInt32(fileSize - sum));
                    }
                    else
                    {
                        count = fs.Read(data, 0, data.Length);
                        network.Write(data, 0, data.Length);
                    }
                    fs.Seek(sum, SeekOrigin.Begin);
                    sum += count;
                    backgroundWorker1.ReportProgress((int)((sum * 100) / fileSize));
                }
                network.Flush();
            }
            finally
            {
                fs.Dispose();
                data = null;
            }
        }
    }

Receive method (SERVER):

FileStream fs;
long sum;
long fileSize;
byte[] data = null;
NetworkStream network; 
const int packetSize = 1024*8;

public void Receive(string destPath, long fileSize)
    {
        using (fs = new FileStream(destPath, FileMode.Create, FileAccess.Write))
        {
            try
            {
                int count = 0;
                long sum = 0;
                data = new byte[packetSize];
                while (sum < fileSize)
                {
                    if (fileSize - sum < packetSize)
                    {
                        count = network.Read(data, 0, Convert.ToInt32(fileSize - sum));
                        fs.Write(data, 0, Convert.ToInt32(fileSize - sum));
                    }
                    else
                    {
                        count = network.Read(data, 0, data.Length);
                        fs.Write(data, 0, data.Length);
                    }
                    fs.Seek(sum, SeekOrigin.Begin);
                    sum += count;
                }
            }
            finally
            {
                fs.Dispose();
                data = null;
            }
        }
    }

2条回答
闹够了就滚
2楼-- · 2019-09-08 07:41

You never take into consideration how many bytes you read from file or network stream. See your count variables in your server & client codes.

You should write count bytes to other stream after reading from input stream.

EDIT

Here is a sample from your code in Receive

count = network.Read(data, 0, data.Length);
fs.Write(data, 0, data.Length);

How can you be sure that you have read data.Length bytes

查看更多
萌系小妹纸
3楼-- · 2019-09-08 07:50

In case you didn't solve it by now, I propose this code. Put it inside while (sum < fileSize).

Send:

    count = fs.Read(data, 0, packetSize);
    network.Write(data, 0, count);
    sum += count;
    backgroundWorker1.ReportProgress((int)((sum * 100) / fileSize));

and Receive:

    count = network.Read(data, 0, packetSize);
    fs.Write(data, 0, count);
    sum += count;

This will ensure that you transfer just the data you have read. Notice that you do not need if part because Read will return number of bytes read, so it doesn't matter if you are at beginning or at end of the file, Read will read all it can up to limit you provided as parameter.

查看更多
登录 后发表回答