【问题标题】:Client aborted when WCF return StreamWCF 返回 Stream 时客户端中止
【发布时间】:2017-12-13 18:16:25
【问题描述】:

我目前正在使用 WCF 服务和 C# 基本 Winform 应用程序。两者都在不同的服务器上。我试图让 C# 应用程序使用 WCF 从其他服务器获取文件。这是 WCF 的代码:

public Stream GetData(string fileName)
{
  string filePath;
  FileStream file = null;
  try
  {
    // Stuff

    file = File.OpenRead(Path.Combine(filePath, fileName));

    file.Position = 0L;

    return (Stream)file;

  }
  catch (Exception ex)
  {
    // Trace stuff
    return Stream.Null;
  } 
}

这是运营合同:

[OperationContract]
Stream GetData(string fileName);

这是客户端配置文件:

   <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="NetTcpBindingEndpoint"  transferMode="Streamed" closeTimeout ="10:00:00" openTimeout="10:00:00" sendTimeout="10:00:00" receiveTimeout ="10:00:00" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
          <security mode="None" />
        </binding>
      </netTcpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://SERVER/UpdaterUtilsWCF" binding="netTcpBinding"
        bindingConfiguration="NetTcpBindingEndpoint" contract="UpdaterUtilsWCF.IUpdaterUtilsWCF"
        name="NetTcpBindingEndpoint">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>
  </system.serviceModel>

这是 WCF 配置文件:

<system.serviceModel>
   <bindings>
  <netTcpBinding>
    <binding  name="TCPBinding_IDataService" openTimeout="10:00:00"   
                 closeTimeout="10:00:00"   
                 sendTimeout="10:00:00"   
                 receiveTimeout="10:00:00" 
         maxBufferPoolSize="2147483647" 
                 maxBufferSize="2147483647" 
                 maxReceivedMessageSize="2147483647"
         transferMode="Streamed">
      <security mode="None" />
        </binding>
      </netTcpBinding>
    </bindings>
    <services>
      <service name="UpdaterWCF.UpdaterUtilsWCF">
        <endpoint address="" binding="netTcpBinding" bindingConfiguration="TCPBinding_IDataService"
          name="NetTcpBindingEndpoint" contract="UpdaterWCF.IUpdaterUtilsWCF">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
          name="MexTcpBindingEndpoint" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="net.tcp://SERVER/UpdaterUtilsWCF" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="">
          <serviceThrottling maxConcurrentCalls="100"   maxConcurrentInstances="2147483647" maxConcurrentSessions="200" />
          <dataContractSerializer maxItemsInObjectGraph="2147483646"/>
          <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

最大并发调用、实例和会话在 WCF 配置文件中设置为最大值。

这是客户端应用程序的代码:

    using (Stream stream = WCFClient.GetData(textBox1.Text))
    {
      // stuff
    }

当我执行应用程序时,它在客户端(或 WCF 端)崩溃,但是当 Stream 被传递到客户端应用程序时。我已经跟踪了 WCF 上的代码,并且已经进行了调用,并且在 WCF 结束时调用了返回代码。调用后立即出现错误,文件非常小(400kb) 这是错误:

System.ServiceModel.CommunicationException: 套接字连接被中止。这可能是由错误引起的 处理您的消息或远程超出接收超时 主机或底层网络资源问题。本地套接字超时为 '10:00:00'。 System.Net.Sockets.SocketException:强制现有连接 被远程主机关闭 在 System.Net.Sockets.Socket.Receive(Byte[] 缓冲区,Int32 偏移量,Int32 大小,SocketFlags socketFlags) 在 System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] 缓冲区, Int32 偏移量、Int32 大小、TimeSpan 超时、布尔关闭)

请帮帮我。

  • 已编辑我已为这两个应用添加了整个 system.model

【问题讨论】:

    标签: c# .net wcf stream


    【解决方案1】:

    根据我的经验,这通常是配置中的问题。确保您从一个已知的好例子开始。微软的例子在这里: https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-enable-streaming 可能是一个好的开始。 设置所有三个缓冲区大小或使用只有几个字符的文件进行测试,以在发送更大的文件之前验证基本功能。

    <basicHttpBinding>
      <binding name="HttpStreaming" maxBufferPoolSize="2147483647" 
    maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" transferMode="Streamed"/>
    
    </basicHttpBinding>
    <!-- an example customBinding using Http and streaming-->
    <customBinding>
      <binding name="Soap12">
        <textMessageEncoding messageVersion="Soap12WSAddressing10" />
        <httpTransport transferMode="Streamed" maxReceivedMessageSize="67108864"/>
      </binding>
    </customBinding>
    

    【讨论】:

    • 我已经编辑了我的问题(配置文件部分)并尝试了缓冲区大小的所有最大值,甚至所有并发缓冲区值和配额。仍然有同样的错误。
    • @Alexandre,如果您为客户端和服务器发布整个 system.serviceModel 部分,它可能会对此有所了解。
    【解决方案2】:

    经过一番调试,我发现了问题所在。在我的 WCF 服务代码中,我在 try - catch 之后实现了流资源释放:

        finally
        {
          if (file != null)
          {
            file.Close();
            file = null;
          }
        }
    

    当客户端接收流时,WCF 端的流正在关闭。

    这是我找到答案的地方: IOException on streamed file upload via WCF over HTTP

    【讨论】:

      猜你喜欢
      • 2011-05-05
      • 1970-01-01
      • 2012-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多