简体   繁体   中英

Client aborted when WCF return Stream

I'm currently playing with a WCF service and a C# basic Winform application. Both are on different server. I'm trying to have the C# application get a file from the other server using a WCF. Here's the code for the 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;
  } 
}

and this is the operation contract:

[OperationContract]
Stream GetData(string fileName);

This is the client configuration file:

   <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>

and this is the WCF configuration file:

<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>

Max concurrent calls, instances and sessions are set to maximum in the WCF configuration file.

This is the code for the client application:

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

When i execute the application, it crash on the client side (or the WCF side) but when the Stream is passed to the client application. I have trace the code on the WCF and the call have been made and the return code is called at the end of the WCF. The error appear immediately after the call and the file is very small (400kb) Here's the error:

System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '10:00:00'. System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags) at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)

Please help me with this.

  • EDITED I'v added entire system.model for both app

In my experience, this is usually a problem in the configuration. Make sure you are following a known good example to start. The Microsoft example is here: https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-enable-streaming may be a good start. Set all three buffer sizes or test with a file that is only a few characters to verify basic functionality before sending a larger file.

<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>

After a bunch of debugging, i've found the problem. In my WCF service code i've implemented the stream ressource release after the try - catch:

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

The Stream was closing on the WCF side while the client was receiving the Stream.

This is where i found my answer: IOException on streamed file upload via WCF over HTTP

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM