Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用.NET客户端连接时间流式传输文件?_C#_Logging_Streaming_Download - Fatal编程技术网

C# 使用.NET客户端连接时间流式传输文件?

C# 使用.NET客户端连接时间流式传输文件?,c#,logging,streaming,download,C#,Logging,Streaming,Download,不久前我问了一个关于使用C#()保护下载的问题,我得到了一些很好的建议(包括将文件读入内存,然后将其写入用户)。唯一的问题是,现在我正试图实现一些基本的日志记录,我遇到了麻烦。以下是流式传输文件的代码: public void StreamFile(string file_path) { DateTime start; TimeSpan ts; FileStream fstream; string filename = Path.GetFileName(file_

不久前我问了一个关于使用C#()保护下载的问题,我得到了一些很好的建议(包括将文件读入内存,然后将其写入用户)。唯一的问题是,现在我正试图实现一些基本的日志记录,我遇到了麻烦。以下是流式传输文件的代码:

public void StreamFile(string file_path)
{
    DateTime start;
    TimeSpan ts;
    FileStream fstream;
    string filename = Path.GetFileName(file_path);
    byte[] buffer = new byte[STREAM_BUFFER_SIZE];
    int count = 1, total = 0, seconds;

    // Open the file to read
    fstream = new FileStream("D:\\" + file_path, FileMode.Open, FileAccess.Read);

    // Set up the response headers
    Response.AddHeader("Content-Length", fstream.Length.ToString());
    Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
    Response.ContentType = "application/octet-stream";

    // If the user agent is Internet Explorer, we add one last header
    if (Request.UserAgent.Contains("MSIE"))
        Response.AddHeader("Content-Transfer-Encoding", "binary");

    // Start counting the time
    start = DateTime.Now;

    // Now, until the client disconnects, we stream the file
    while (Response.IsClientConnected)
    {
        // Read the file into the buffer
        count = fstream.Read(buffer, 0, buffer.Length);

        // If the buffer is empty, break out of the loop. We're done!
        if (count == 0)
            break;

        // Write to the output stream and push it to the user
        Response.OutputStream.Write(buffer, 0, count);
        Response.Flush();

        // Increment the total as well, this way we can know how much we've streamed
        total += count;
    }
    // The transfer is done! Close the connection.
    Response.Close();

    // Count the number of seconds
    ts = DateTime.Now - start;
    seconds = ts.Seconds + (60 * ts.Minutes) + (60 * 60 * ts.Hours); // Also, is there a better way to do this? This is laaaaaame!

    // Finally, log the transfer
    Logging.AddLog(Request["user"], file_path, total, count == 0, seconds);
}
好的,所以问题是,创建的日志条目表示文件在将文件读入内存所用的秒数内完成,而不是用户下载文件所用的秒数。我猜是这样的。ClientConnected会处理这个问题,但显然不是。因此,日志报告的下载文件的时间是0-1秒,即使我中途停止下载,日志也说它提供了全部内容


以前有没有人做过类似的事情,或者有没有人知道我如何获得转会背后的真实数字?不幸的是,拥有这些信息是一个非常重要的优先事项,或者我只是耸耸肩,将这两个值从日志中删除。

很抱歉,但可能无法完成您想要做的事情。在调用()之后(在上),数据将立即提供给Windows的套接字,后者将数据写入网卡的缓冲区。因此,.Net不会立即执行任何缓冲和写入返回。由于.Net不缓冲NetworkStream,因此调用()无效。因此,从.Net中不可能等到数据离开网卡的缓冲区


即使您设法精确地等待数据离开NIC的缓冲区,也不能保证客户端曾经收到数据。

解决方案是让您的客户端应用程序在收到整个文件后发送“已接收”的确认数据包。一旦你收到,你就知道他们实际上收到了全部信息,并且可以停止计时器。

除了标准的web浏览器之外,没有“客户端应用程序”,否则日志记录会发生在客户端,这样信息会更准确。嗯,这将是我的接受,除非有人能想出一个方法来做到这一点。见鬼,也许我只能求助于解析IIS日志来获得我需要的东西。