views:

31

answers:

1

I'm writing a WCF (net.tcp) file transfer service which will eventually split files into several pieces and transfer said pieces to the client from the server/service. Currently the client and server are console apps.

While writing this service, I have at various times gotten the following exception;

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 '01:59:59.4220000'.

Actually, it starts as a Unhandled Exception: System.Reflection.TargetInvocationException: An exception occurred during the operation, making the result invalid. Check InnerException for exception details. ---> then the CommunicationException text above is right here.

In typical Microsoft fashion, that exception message is beyond unhelpful, so I'm finally calling out to the community to see if I can tackle this issue.

Also, in case this is important, the client is calling two of the service's methods Asynchronously ( InitGetFilePart() and GetFilePart() ). According to my logs, the first call to InitGetFilePartAsync(1, 1) gets handled all the way to the end; meaning that it's 'Completed' handler is called, which in turn calls vcClient.GetFilePartAsync(FileXferCargo, 1), and it's handler then spawns a BackgroundWorker thread (workers[chunkNum]. RunWorkerAsync(cargoHolder[chunkNum] where chunkNum=1) which itself completes. This is right about the time I get the TargetInvocationException mentioned above.

In the past I have made various tweaks (sadly, I can't remember what exactly) to the App.config to make this exception go away, but now nothing I do seems to make any difference and I just do NOT understand why this keeps happening.

I have read other advice on this matter, including "You have to catch the exception on the client, Abort current proxy and create and open new one." Well, I tried that but it doesn't appear I am able to catch this exception.

I also read that it could be due to sending too much data over the wire, but when I try to send my little 4k test file, I get the same exception. During my investigations, I also read that I can call 1 WCF service function/method, many times using the *Async() calls with the UserState parameter, which I am doing.

I will admit to being a relitive n00b when it comes to WCF, but I'm pretty sure I have my config files set correctly for what I'm trying to do.

Here are the client and server app.config files, the service interface definition and the top of the service's implementation class.

Client's App.config:

<system.serviceModel>

    <bindings>
        <netTcpBinding>
            <binding name="MyTcpBinding_IFileXferService"
                     receiveTimeout="02:00:00"
                     sendTimeout="02:00:00"
                     transferMode="Streamed"
                     maxBufferSize="65536"
                     maxReceivedMessageSize="2147483647">
                <readerQuotas maxStringContentLength="2147483647"
                              maxArrayLength="2147483647"
                              maxBytesPerRead="65536" />
                <security mode="Transport">
                    <transport clientCredentialType="None">
                        <extendedProtectionPolicy policyEnforcement="Never" />
                    </transport>
                </security>
            </binding>
        </netTcpBinding>
    </bindings>

    <behaviors>
        <endpointBehaviors>
            <behavior name="ClientConfigBehavior">
                <dataContractSerializer maxItemsInObjectGraph="2147483647" />

                <clientCredentials>
                    <serviceCertificate>
                        <authentication certificateValidationMode="None" />
                    </serviceCertificate>
                </clientCredentials>

            </behavior>
        </endpointBehaviors>
    </behaviors>

    <client>
        <endpoint name="ClientConfig"
                  behaviorConfiguration="ClientConfigBehavior"
                  binding="netTcpBinding"
                  bindingConfiguration="MyTcpBinding_IFileXferService"
                  contract="ServiceRefs.IFileXferService" />
    </client>

</system.serviceModel>

Server's App.config:

    <bindings>
        <netTcpBinding>
            <!-- Under <netTcpBinding> setting the listenBacklog, 
                maxConnections, and maxBuffer* values high -->
            <binding name="MyTcpBinding_IFileXferService"
                 receiveTimeout="02:00:00"
                 sendTimeout="02:00:00"
                 openTimeout="00:01:00"
                 transferMode="Streamed"
                 portSharingEnabled="true"
                 listenBacklog="32"
                 maxConnections="64"
                 maxBufferSize="65536"
                 maxReceivedMessageSize="2147483646">
                <security mode="Transport">
                    <transport clientCredentialType="None" />
                </security>
            </binding>
        </netTcpBinding>

    </bindings>

    <services>
        <service name="MediaServer.LNMediaServerSvc"
                 behaviorConfiguration="ServerConfigBehavior">
            <host>
                <baseAddresses>
                    <add baseAddress="net.tcp://lngsead148191a:9000/fileXferSvc"/>
                </baseAddresses>
            </host>
            <endpoint name="mainEndPoint"
                      binding="netTcpBinding"
                      bindingConfiguration="MyTcpBinding_IFileXferService"
                      contract="ServiceInterfaces.IFileXferService" />
        </service>
    </services>

    <behaviors>
        <serviceBehaviors>
            <behavior name="ServerConfigBehavior">
                <serviceDebug includeExceptionDetailInFaults="true"/>
                <serviceThrottling maxConcurrentCalls="64" />
                <dataContractSerializer maxItemsInObjectGraph="2147483646" />
                <serviceCredentials>
                    <serviceCertificate findValue="tp_value"
                                        x509FindType="FindByThumbprint" />
                </serviceCredentials>
            </behavior>
        </serviceBehaviors>
    </behaviors>

</system.serviceModel>

The Service interface is defined as follows;

[DataContract(IsReference = true)]
public class FileData
{
    private long m_startPos;

    [DataMember]
    public long StartPosition
    {
        get { return m_startPos; }
        set { m_startPos = value; }
    }

    private long m_endPos;

    [DataMember]
    public long EndPosition
    {
        get { return m_endPos; }
        set { m_endPos = value; }
    }

    private byte m_chunkNumber;

    [DataMember]
    public byte ChunkNumber
    {
        get { return m_chunkNumber; }
        set { m_chunkNumber = value; }
    }

    private long m_chunkSize;

    [DataMember]
    public long ChunkSize
    {
        get { return m_chunkSize; }
        set { m_chunkSize = value; }
    }

    private string md5Hash;

    [DataMember]
    public string MD5Hash
    {
        get { return md5Hash; }
        set { md5Hash = value; }
    }

    private string m_destFileSpec;

    [DataMember]
    public string DestinationFileSpec
    {
        get { return m_destFileSpec; }
        set { m_destFileSpec = value; }
    }

    private string m_srcFileSpec;

    [DataMember]
    public string SourceFileSpec
    {
        get { return m_srcFileSpec; }
        set { m_srcFileSpec = value; }
    }

    private Stream m_sourceStream;

    [DataMember]
    public Stream SourceStream
    {
        get { return m_sourceStream; }
        set { m_sourceStream = value; }
    }

    private UInt32 m_JobNo;

    [DataMember]
    public UInt32 JobNumber
    {
        get { return m_JobNo; }
        set { m_JobNo = value; }
    }

    private UInt32 m_fileNumber;

    [DataMember]
    public UInt32 FileNumber
    {
        get { return m_fileNumber; }
        set { m_fileNumber = value; }
    }

    private long m_fileSize;

    [DataMember]
    public long FileSize
    {
        get { return m_fileSize; }
        set { m_fileSize = value; }
    }
}


[DataContract]
public partial class FileXferCargo
{
    private FileData m_fileData;

    [DataMember]
    public FileData FileData
    {
        get { return m_fileData; }
        set { m_fileData = value; }
    }


    private bool m_cancelled;

    [DataMember]
    public bool Cancelled
    {
        get { return m_cancelled; }
        set { m_cancelled = value; }
    }

    private long m_errorCode;

    [DataMember]
    public long ErrorCode
    {
        get { return m_errorCode; }
        set { m_errorCode = value; }
    }

    private Exception m_exceptionObj;

    [DataMember]
    public Exception Exception
    {
        get { return m_exceptionObj; }
        set { m_exceptionObj = value; }
    }
}


[ServiceContract]
public interface IFileXferService
{
    [OperationContract]
    bool InitFileRequest(ref FileXferCargo fileRequest);

    [OperationContract]
    bool InitGetFilePart(ref FileXferCargo fileCargo);

    [OperationContract]
    Stream GetFilePart(FileXferCargo fileCargo);

    [OperationContract]
    int CloseFile(FileData fileData);
}

The Service implementation class is defined as follows;

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, 
    ConcurrencyMode = ConcurrencyMode.Multiple,
    UseSynchronizationContext = false)
]
public class LNMediaServerSvc : IFileXferService
{
    ...
}
A: 

Don't have a comment button anymore so I'll put this here. Yes, I have turned on tracing, but it seems like I'm going to need to read a BOOK to understand all the stuff the trace data is trying to tell me. That said, I looked over the trace info and the one thing I couldn't see was anything leading up to the socket being aborted. Just seems to happen for no reason. :(

Scott K. Fraley