TcpClient VS Socket在大文件传输中

Bła*_*żej 2 .net c# sockets

我必须trnasfer大文件,此时我使用TcpClient和NetworkStream类来做到这一点,但它并不是真的.当我使用NetworkStream.Write和Read它丢失字节时,我不知道如何确保TCP在所有字节都可以正常时停止读取.

然后我找到了Socket Class,现在我的问题是,"Socket会在它结束读取之前完全确定所有字节吗?"

我如何回复文件:

            byte[] VideoFrom = new byte[FizeSizeSendedBefore];
            byte[] PartData = new byte[clientSocket.ReceiveBufferSize];
            int PartNumbers = (VideoSize / clientSocket.ReceiveBufferSize) + 1;
            int lastPackageSize = VideoSize - ((PartNumbers - 1) * clientSocket.ReceiveBufferSize);

            int i;
            int bytesToRead = 0;
            int ActualSize = 0;
            for (i = 0; i < PartNumbers; i++)
            {
                if (i < PartNumbers - 1)
                {
                    bytesToRead = clientSocket.ReceiveBufferSize;
                }
                else
                {

                    bytesToRead = lastPackageSize;
                }
                ActualSize += bytesToRead;


                PartData = new byte[bytesToRead];

                System.Threading.Thread.Sleep(2);

                networkStream.Read(PartData, 0, bytesToRead);

                Buffer.BlockCopy(PartData, 0, VideoFrom, i * clientSocket.ReceiveBufferSize, bytesToRead);
            }



            if (!Directory.Exists("./temp/anwsers/" + AnwserXML.Attribute("number").Value)) { Directory.CreateDirectory("./temp/anwsers/" + AnwserXML.Attribute("number").Value); }
            File.WriteAllBytes("./temp/anwsers/" + AnwserXML.Attribute("number").Value + "/" + AnwserXML.Attribute("client").Value + ".mov", VideoFrom);


        }
Run Code Online (Sandbox Code Playgroud)

我如何发送文件

int PartNumber = (FizeSizeSendedBefore/ clientSocket.ReceiveBufferSize) + 1;
            int lastPackageSize = FileSize - ((PartNumber - 1) * clientSocket.ReceiveBufferSize);
            int i;
            for (i = 0; i < PartNumber; i++)
            {
                if (i < PartNumber - 1)
                {
                    while (!serverStream.CanRead) { }
                    serverStream.Write(outStream, i * clientSocket.ReceiveBufferSize, clientSocket.ReceiveBufferSize);
                }
                else
                {
                    while (!serverStream.CanRead) { }
                    serverStream.Write(outStream, i * clientSocket.ReceiveBufferSize, lastPackageSize);
                }

            }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 6

这就是问题:

networkStream.Read(PartData, 0, bytesToRead);
Run Code Online (Sandbox Code Playgroud)

永远不要忽略它的返回值Read.永远不要假设一次读取调用将读取所有数据.你需要循环,阅读,直到它全部"进入".以呼叫数目Read所需要读取所有数据是非常无关的呼叫的数量Write.TCP是一种协议 - 以这种方式对待它.

目前尚不清楚您是否确切知道您期望阅读的数据量 - 您呢?服务器会在最后关闭连接吗?如果是这样,如果你正在使用.NET 4,那么你就可以摆脱一个的巨大这段代码的数量:

using (Stream output = File.Create(filename))
{
    networkStream.CopyTo(output);
}
Run Code Online (Sandbox Code Playgroud)