我在使用WCF流式传输文件时遇到了一些麻烦。我能够将文件流式传输到小于300 MB的服务器,但是当我尝试300 MB或更多的文件时,我在“已建立的连接被主机中的软件中止”时出现大约60%的错误。这个错误听起来像我在文件完成之前关闭了连接,但我找不到它。
我打开连接的客户端代码,调用Upload Method,等待返回,然后关闭连接。这适用于小文件。
WCF服务器使用net.tcp绑定托管在Windows服务中。我已经尝试过更改缓冲区大小等,但仍然没有运气。
我正在寻找一些帮助来追踪这个问题。
服务器端绑定:
NetTcpBinding tcp = new NetTcpBinding(SecurityMode.None);
tcp.SendTimeout = TimeSpan.FromMinutes(10);
tcp.ReceiveTimeout = TimeSpan.FromMinutes(10);
tcp.MaxBufferSize = 65536; // 16384;
tcp.MaxBufferPoolSize = 204003200; // 655360;
tcp.MaxReceivedMessageSize = 204003200; // 2147483647;
tcp.TransferMode = TransferMode.Streamed;
tcp.ReaderQuotas = new XmlDictionaryReaderQuotas()
{
MaxArrayLength = 2147483647
};
客户端绑定:
NetTcpBinding tcp = new NetTcpBinding(SecurityMode.None);
tcp.SendTimeout = TimeSpan.FromMinutes(10);
tcp.ReceiveTimeout = TimeSpan.FromMinutes(10);
tcp.MaxBufferSize = 65536; // 16384;
tcp.MaxBufferPoolSize = 204003200; // 655360;
tcp.MaxReceivedMessageSize = 204003200; // 2147483647;
tcp.TransferMode = TransferMode.Streamed;
tcp.ReaderQuotas = new XmlDictionaryReaderQuotas()
{
MaxArrayLength = 2147483647
};
我用于文件流的类:
[MessageContract]
public class DataFileStream
{
[MessageHeader(MustUnderstand = true)]
public String ID { get; set; }
[MessageHeader(MustUnderstand = true)]
public String FileName { get; set; }
[MessageHeader(MustUnderstand = true)]
public long FileSize { get; set; }
[MessageBodyMember(Order = 1)]
public Stream StreamData { get; set; }
}
我收到的错误:
异常:套接字连接已中止。这可能是由于处理消息的错误或远程主机超出接收超时或基础网络资源问题引起的。本地套接字超时为'00:48:35.9230000'
内部异常:写入操作失败,请参阅内部异常。
内部异常:套接字连接已中止。这可能是由于处理消息的错误或远程主机超出接收超时或基础网络资源问题引起的。本地套接字超时为'00:48:35.9230000'。
内部异常:已建立的连接已被主机中的软件中止
提前感谢您的帮助。
答案 0 :(得分:0)
我认为这是因为您将MaxReceivedMessageSize
(可能MaxBufferPoolSize
)设置为大约194兆字节。尝试将其加倍到408006400
(约400mb)。
将其更改为:
tcp.MaxBufferPoolSize = 408006400;
tcp.MaxReceivedMessageSize = 408006400;
阅读MSDN,我不认为MaxBufferPoolSize
会成为问题(但值得增加它只是为了确保)。如果这样做,将其重置为200mb的限制并再次测试。
发生这种情况的原因是,一旦服务器传输了204003200字节(194mb),服务器就会中止传输,因为您指出了最大预期大小。这是为了防止恶意使用,有人上传一个非常大的文件来阻塞服务器或防止用户过度使用。