我已经开始使用 C# 学习 TCP 网络。我遵循了各种教程并查看了那里的示例代码,并通过异步连接和写入/读取有一个工作的 TCP 服务器和客户端。我的文件传输也正常。
现在我希望能够在服务器和客户端上跟踪传输进度 (0% -> 100%)。在启动从服务器到客户端的传输时,我发送了预期的文件大小,因此客户端知道预期有多少字节,所以我想我可以轻松地在客户端上执行:curCount/totalCount。但我对如何为服务器执行此操作感到有点困惑。
服务端能准确告诉客户端传输情况吗?我应该根据服务器自身的状态来猜测吗(通过 networkStream.BeginWrite() 回调,或者通过从磁盘加载 block 和网络写入)?或者我应该让客户端将客户端的完成情况中继回服务器吗?
我想知道何时关闭连接,以及能够直观地显示进度。服务器是否应该信任客户端关闭连接(除非网络错误/超时/等)?或者服务器是否可以在写入流后立即关闭连接?
最佳答案
这里有两个不同的完成百分比:客户端的和服务器的。如果您认为服务器在发送完最后一个字节后就完成了,那么服务器的百分比将始终至少与客户端的百分比一样高。如果您认为服务器在客户端处理完最后一个字节时完成,则服务器的百分比将滞后于客户端之一。无论您做什么,两端都会有不同的值(value)观。
值将根据当前在服务器应用程序和客户端应用程序之间的各种缓冲区中排队的数据量而有所不同。这个缓冲空间通常很小。据我所知,最大 TCP 窗口大小默认为 200 毫秒的数据传输。
或许,您根本不需要担心这个问题,因为双方的进度值将紧密相关。
Should I guess based on the server's own status (either via the networkStream.BeginWrite() callback, or via the chunk loading from disk and networking writing)?
这是一个合适的解决方案。
Or should I have the client relay back to the server the client's completion?
这将是我在第 1 段中描述的第二种情况。也可以接受,尽管不一定是更好的结果和更多的开销。我现在无法想象我会这样做的情况。
Should the server trust the client to close the connection (barring network errors/timeouts/etc)?
当 TCP 交换的一方完成发送时,它应该关闭用于发送的套接字(使用 Socket.Shutdown(Send)
)。这将导致对方读取零字节并知道传输已完成。
在关闭一个套接字之前,它应该被关闭。如果 Shutdown
调用没有错误地完成,则可以保证远程方已收到所有数据,并且本地方也已收到所有数据。
Or can the server close the connection as soon as it's written to the stream?
先关机,后关闭。仅关闭并不意味着传输成功。
关于c# - 跟踪文件传输百分比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22946361/