我正在编写一个WCF(net.tcp)文件传输服务,该服务最终会将文件分成几个部分,并将所述部分从服务器/服务传输到客户端。目前客户端和服务器是控制台应用程序。
在编写此服务时,我在不同时间遇到以下异常;
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],其中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>
服务接口定义如下;
[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 :(得分:3)
对于netTcpBinding,在客户端和服务器配置文件上将安全模式设置为none:
<security mode="None" />
这是一个快速修复。
如果您需要为netTcpBinding启用安全性,则必须实现委派和模拟。
在此处阅读更多内容:http://msdn.microsoft.com/en-us/library/ms730088.aspx
根据我的阅读和谷歌搜索,这是一个多跳模拟的问题。模拟只能进行一跳。通过将安全模式设置为none,可以在调用WCF服务时阻止身份验证步骤。
答案 1 :(得分:0)
不再有评论按钮,所以我会把它放在这里。是的,我已经开启了跟踪,但似乎我需要阅读一本书来了解跟踪数据试图告诉我的所有内容。也就是说,我查看了跟踪信息,我看不到的是导致套接字被中止的任何事情。似乎没有任何理由发生。 :(
答案 2 :(得分:0)
对我来说,这是因为托管WCF的服务器中的web.config中没有net.tcp绑定。当我为服务添加相同的绑定时,我没有得到异常。因此,如果它们托管在不同的服务器中,则需要在Web和WCF中双方进行绑定。