首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TcpClient与Socket在大文件传输中的对比

TcpClient与Socket在大文件传输中的对比
EN

Stack Overflow用户
提问于 2012-03-30 17:44:14
回答 3查看 4.4K关注 0票数 2

我必须传输大文件,目前我使用TcpClient和NetworkStream类来传输,但这还不够。当我使用NetworkStream.Write读取丢失的字节时,我不知道如何确保TCP在所有字节都正常时停止读取。

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

我如何接收文件:

代码语言:javascript
复制
            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);


        }

如何发送文件

代码语言:javascript
复制
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);
                }

            }
EN

回答 3

Stack Overflow用户

发布于 2012-03-30 18:11:42

这就是问题:

代码语言:javascript
复制
networkStream.Read(PartData, 0, bytesToRead);

从不忽略Read的返回值。从不假设对的一次调用将读取所有数据。你需要循环阅读,直到读完为止。读取所有数据所需的对Read的调用次数与对Write的调用次数几乎无关。TCP是一种流协议--就这样看待它吧。

还不清楚你是否确切地知道你想要读取多少数据--是吗?服务器会在结束时关闭连接吗?如果是这样的话,如果你使用的是.NET 4,那么你可以去掉大量的代码:

代码语言:javascript
复制
using (Stream output = File.Create(filename))
{
    networkStream.CopyTo(output);
}
票数 6
EN

Stack Overflow用户

发布于 2012-03-30 17:52:30

你的文件有多大?也许这将是足够的WebClient.DownloadDataAsync(...)

更新了,如果文件大小约为100Mb,请使用简单WebClient :)

代码语言:javascript
复制
        WebClient wc = new WebClient();
        wc.DownloadDataCompleted += new DownloadDataCompletedEventHandler(OnDownloadDataCompleted);
        wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(OnDownloadProgressChanged);
        wc.DownloadDataAsync(new Uri("http://www.xxxx.com/t.tar.gz"));
票数 0
EN

Stack Overflow用户

发布于 2012-03-30 17:59:23

TCP将一次接收一块数据-它不会丢失数据,但如果您不考虑这样的事实,即数据将被分成数据包,并将一个接一个地到达,并且(通常)不是作为一个大的“文件”到达,那么您可能不会侦听其余的数据-这看起来像是丢失了数据,但实际上是代码在收到第一个数据包后忽略了其余的数据。仅仅因为你把它放在一个包里,这并不意味着它会在一个包里到达。

在google的奇妙世界中,有许多TCP服务器/客户端应用程序(和聊天应用程序)供您比较笔记-或者发布您的代码,然后我们可以看到错误所在。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9940577

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档