2010-10-05 80 views
2

我正在写一个WCF(net.tcp)文件传输服务,它将最终将文件拆分成多个部分,并将所述部分从服务器/服务传输到客户端。目前客户端和服务器是控制台应用程序。WCF net.tcp唯一的服务给TargetInvocationException/ServiceModel.CommunicationException

在写这个服务的时候,我在不同的时候得到了以下例外;

System.ServiceModel.CommunicationException:套接字连接被中止。这可能是由处理您的消息时出错或远程主机超出接收超时或基础网络资源问题引起的。本地套接字超时为'01:59:59.4220000'。

实际上,它以未处理的异常开始:System.Reflection.TargetInvocationException:操作过程中发生异常,导致结果无效。检查异常详情的InnerException。 --->那么上面的CommunicationException文本就在这里。

在典型的微软时尚中,这个异常消息已经无可救药,所以我终于向社区发出呼吁,看看我是否可以解决这个问题。此外,如果这很重要,客户端会异步调用两个服务的方法(InitGetFilePart()和GetFilePart())。根据我的日志,第一次调用InitGetFilePartAsync(1,1)会一直处理到最后;这意味着调用了'Completed'处理程序,该处理程序又调用vcClient.GetFilePartAsync(FileXferCargo,1),然后它的处理程序生成一个BackgroundWorker线程(workers [chunkNum]。 RunWorkerAsync(cargoHolder [chunkNum] where chunkNum = 1)which本身就完成了这是正确的关于我得到上面提到的TargetInvocationException

在过去,我已经做了各种调整(遗憾的是,我不记得是什么)到App.config使这个例外消失,但现在我没有做任何事情似乎有所作为,我只是不明白为什么这种情况继续发生。

我已阅读关于此事的其他建议,包括“你必须赶上客户端的异常,中止当前代理并创建并打开ne一个。“那么,我尝试过,但它并没有出现我能够赶上这个例外。

我也读过它可能是由于通过电线发送太多的数据,但是当我尝试发送我的小4k测试文件时,我得到相同的异常。在我的调查过程中,我还了解到,我可以多次使用带有UserState参数的* Async()调用来调用1个WCF服务函数/方法,这正是我正在做的。

当谈到WCF时,我会承认它是一个可重复的n00b,但我确信我的配置文件正确设置了我正在尝试做的事情。

以下是客户端和服务器app.config文件,服务接口定义以及服务实现类的顶部。

客户的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> 

服务器的应用程序。配置:

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

服务接口定义如下;

[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); 
} 

Service实现类定义如下;

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

打开服务和客户端上的WCF跟踪:http://msdn.microsoft.com/en-us/library/ms733025.aspx – 2010-10-05 19:53:21

+1

如果基于HTTP的托管问题将被清除--FileData包含Stream。在Net.Tcp中,我不确定这是否被允许。 – 2010-10-05 19:55:33

+0

该流成员仅在本地用于在多个方法之间传送流。我前一段时间发现,我无法以这种方式返回流,因此2个Init方法,然后是GetFilePart,它是返回实际Stream的那个。 – 2010-10-05 20:22:58

回答

0

没有评论按钮了,所以我会把它放在这里。是的,我打开了跟踪,但似乎我需要阅读一本书来了解跟踪数据试图告诉我的所有内容。也就是说,我查看了跟踪信息,而我看不到的是导致插槽被中止的任何事情。似乎没有理由发生。 :(

3

为了您NetTcpBinding的,设置安全模式无法比拟的,在客户端和服务器的配置文件上都:

<security mode="None" /> 

这是一个快速解决

如果你需要有保障。启用NetTcpBinding的,那么你必须执行授权和模拟

在这里阅读更多:http://msdn.microsoft.com/en-us/library/ms730088.aspx

从我阅读和搜索的内容来看,这是一个多跳模仿的问题。模仿只能转到一跳。通过将安全模式设置为none,您可以在调用WCF服务时防止身份验证步骤。

0

对我来说,这是因为在托管WCF的服务器的web.config中没有net.tcp绑定。当我为服务添加相同的绑定时,我没有得到异常。因此,如果Web和WCF托管在不同的服务器中,则需要在Web和WCF中进行绑定。