我正在尝试编写一个简单的c#应用程序,它从FTP服务器下载大量小文件。
我尝试了两种方法:
1 - 通用套接字编程
2 - 使用FtpWebRequest和FtpWebResponse对象
使用第一种方法时的下载速度(对于同一文件)从1.5s到7s不等,第二种给出的结果相同 - 每次约2.5s。
考虑到这些2.5中的大约1.4s采用启动FtpWebRequest对象的过程(接收数据只有1.1s),差异非常大。
问题是如何为第一种方法实现与第二种方法相同的良好稳定下载速度?
对于第一种方法,问题似乎存在于下面的循环中(因为它占用了大约90%的下载时间):
Int32 intResponseLength = dataSocket.Receive(buffer, intBufferSize, SocketFlags.None);
while (intResponseLength != 0)
{
localFile.Write(buffer, 0, intResponseLength);
intResponseLength = dataSocket.Receive(buffer, intBufferSize, SocketFlags.None);
}
第二种方法的等效代码部分(对于特定文件总是需要大约1.1s):
Int32 intResponseLength = ftpStream.Read(buffer, 0, intBufferSize);
while (intResponseLength != 0)
{
localFile.Write (buffer, 0, intResponseLength);
intResponseLength = ftpStream.Read(buffer, 0, intBufferSize);
}
我尝试过从56b到32kB的缓冲 - 没有显着差异 还在打开的数据套接字上创建流:
Stream str = new NetworkStream(dataSocket);
并阅读它(而不是使用dataSocket.Receive)
str.Read(buffer, 0, intBufferSize);
没有帮助......事实上它甚至更慢。
提前感谢任何建议!
答案 0 :(得分:2)
您需要使用Socket.Poll或Socket.Select方法来检查数据的可用性。您所做的不仅是减慢操作速度,还会导致大量CPU负载。轮询或选择将产生处理器时间,直到数据可用或超时为止。您可以保持相同的循环但包括调用上述方法之一,并使用超时(尝试从10毫秒到500毫秒的值来查找超时,最适合您的任务)。