2

我正在编写一个 WCF (net.tcp) 文件传输服务,该服务最终会将文件拆分为几部分,并将所述部分从服务器/服务传输到客户端。目前客户端和服务器是控制台应用程序。

在编写此服务时,我曾多次遇到以下异常;

System.ServiceModel.CommunicationException:套接字连接已中止。这可能是由于处理您的消息时出错或远程主机超出接收超时,或者是潜在的网络资源问题造成的。本地套接字超时为“01:59:59.4220000”。

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

以典型的 Microsoft 方式,该异常消息毫无帮助,因此我最终向社区呼吁,看看我是否可以解决这个问题。

此外,如果这很重要,客户端将异步调用服务的两个方法( InitGetFilePart() 和 GetFilePart() )。根据我的日志,对 InitGetFilePartAsync(1, 1) 的第一次调用会一直处理到最后;意味着它的“已完成”处理程序被调用,该处理程序又调用 vcClient.GetFilePartAsync(FileXferCargo, 1),然后它的处理程序产生一个 BackgroundWorker 线程 (workers[chunkNum].RunWorkerAsync(cargoHolder[chunkNum] where chunkNum=1) 它本身完成。这是正确的关于我得到上面提到的 TargetInvocationException 的时间。

过去我对 App.config 进行了各种调整(遗憾的是,我不记得究竟是什么)以使这个异常消失,但现在我所做的一切似乎都没有任何区别,我只是不明白为什么这会一直存在正在发生。

我已经阅读了有关此问题的其他建议,包括“您必须在客户端捕获异常,中止当前代理并创建并打开新代理”。好吧,我试过了,但似乎我无法捕捉到这个异常。

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

当谈到 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>

服务器的 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>

Service接口定义如下;

[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
{
    ...
}
4

3 回答 3

3

对于您的 netTcpBinding,在客户端和服务器配置文件中将安全模式设置为无:

<security mode="None" />

这是一个快速修复。

如果您需要为 netTcpBinding 启用安全性,那么您必须实现委托和模拟。

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

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

于 2011-03-01T01:04:15.907 回答
0

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. :(

于 2010-10-06T14:14:49.363 回答
0

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

于 2013-07-17T13:04:09.487 回答