【问题标题】:Getting System.Net.WebException: The underlying connection was closed but cannot fix it获取 System.Net.WebException:底层连接已关闭但无法修复
【发布时间】:2012-10-24 09:48:31
【问题描述】:

我在堆栈中阅读了许多博客和许多问题,但找不到我的确切场景(实际上非​​常简单)。

上下文

我在 Visual Studio 2010 项目的库中编写了一项服务。我为服务契约和实现该契约的服务类编写了接口。

namespace MyNS.WebSrvLibrary {
[ServiceContract(Namespace = "http://schemas.dummy.com")]
public interface IEchoService {
  [OperationContract()]
  EchoMessageResponse Echo(EchoMessage msg);
}
}

服务:

namespace MyNS.WebSrvLibrary {
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
public class EchoService : IEchoService {
  public EchoService() {}
  [OperationBehavior()]
  public virtual EchoMessageResponse Echo(EchoMessage msg) {
    return new EchoMessageResponse("Ciccio");
  }
  public static IEchoService GetChannel(string addr = "") {
    // Create the service endpoint
    Binding binding = new BasicHttpBinding();
    ServiceEndpoint endpoint =
      new ServiceEndpoint(
            ContractDescription.GetContract(typeof(IEchoService)),
            binding,
            new EndpointAddress(addr));
    // Create channel factory and get proper channel for service.
    ChannelFactory<IEchoService> channelFactory = new ChannelFactory<IEchoService>(endpoint);
    IEchoService svc = channelFactory.CreateChannel();
    return svc;
  }
}
}

EchoMessageResponseEchoMessage 之类的类应用了 DataContracts,它们没问题。

我之前所说的服务被编译成一个 dll(程序集),我只需添加一个引用就可以将它导入到 bin 文件夹中的 Web 应用程序中。在这个 Web 应用程序中,我有用于 Web 服务的 svc 文件:

<%@ ServiceHost Language="C#" Debug="true" Service="MyNS.WebSrvLibrary.EchoService" %>

这是Web.config 文件:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="MyNS.WebSrvLibrary.EchoService">
        <endpoint name="basicHttpBinding" address="" 
                                     binding="basicHttpBinding" 
                                     bindingConfiguration="basicHttpBinding_Svc"
                                     contract="MyNS.WebSrvLibrary.IEchoService"/>
        <endpoint name="mexHttpBinding" address="/Mex"
                                     binding="mexHttpBinding"
                                     contract="IMetadataExchange"/>
      </service>
    </services>
    <bindings>
      <basicHttpBinding>
        <binding maxReceivedMessageSize="2147483647" openTimeout="12:00:00" receiveTimeout="12:00:00" closeTimeout="12:00:00" sendTimeout="12:00:00">
          <readerQuotas maxStringContentLength="1310720"
                        maxArrayLength="16384"
                        maxBytesPerRead="24096"
                        maxDepth="10000"
                        maxNameTableCharCount="16384"/>
        </binding>
        <binding name="basicHttpBinding_Svc" maxReceivedMessageSize="2147483647" openTimeout="12:00:00" receiveTimeout="12:00:00" closeTimeout="12:00:00" sendTimeout="12:00:00">
          <readerQuotas maxStringContentLength="1310720"
                        maxArrayLength="16384"
                        maxBytesPerRead="24096"
                        maxDepth="10000"
                        maxNameTableCharCount="16384"/>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

所以,最后,我有一个客户端应用程序编译成可执行的.exe 文件,如下所示:

class Program {
  static void Main(string[] args) {
    IEchoService svc = EchoService.GetChannel("http://localhost:80/T/Service.svc");
    EchoMessageResponse rmsp = svc.Echo(new EchoMessage("Hello"));
    System.Threading.Thread.Sleep(10000);
  } /* Main */
} /* Program */

关于服务器端事务的信息

Web 应用程序托管在 IIS 中的 默认网站 中,当然要监听端口 80。

问题

当我运行我的可执行应用程序时,我得到了这个System.ServiceModel.CommunicationException 异常:

接收到的 HTTP 响应时出错 http://localhost/T/Service.svc。这可能是由于服务 端点绑定不使用 HTTP 协议。这也可能是由于 到被服务器中止的 HTTP 请求上下文(可能是由于 到服务关闭)。有关详细信息,请参阅服务器日志。

innerException 的类型为:System.Net.WebException

底层连接已关闭:发生意外错误 一个接收。

谁的innerException(异常树中的最后一个)的类型是System.Net.Sockets.SocketException

一个现有的连接被远程主机强行关闭。

完整的堆栈如下:

服务器堆栈跟踪:在 System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest 请求, HttpAbortReason abortReason)
在 System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(时间跨度 超时)在 System.ServiceModel.Channels.RequestChannel.Request(消息消息, TimeSpan 超时)在 System.ServiceModel.Dispatcher.RequestChannelBinder.Request(消息 消息,TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannel.Call(字符串动作, Boolean oneway, ProxyOperationRuntime 操作, Object[] ins, Object[] 出局,TimeSpan 超时)在 System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall,ProxyOperationRuntime 操作)在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 留言)

在 [0] 处重新抛出异常:在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg)在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(消息数据& msgData,Int32 类型)在 DDBR.DiscoveryServiceLibrary.IEchoService.Echo(EchoMessage msg) 在 DDBR.TestClient.Program.Main(String[] args) 在 C:\Data\ROOT_APPS\DistributedDataBackupAndRecovery\TestClient\Program.cs:line 20 在 System.AppDomain._nExecuteAssembly(RuntimeAssembly 程序集, System.AppDomain.ExecuteAssembly(String) 处的 String[] args) 装配文件,证据装配安全,字符串 [] 参数)在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback 回调、对象状态、布尔值 ignoreSyncCtx) 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback 回调、对象状态)在 System.Threading.ThreadHelper.ThreadStart()

可以在第一个异常的StackTrace 属性中找到(初始异常,而不是内部异常)。

很奇怪的东西……

非常奇怪的是,如果我打开浏览器并输入:

http://localhost/T/Service.svc

我看到了著名的 Microsoft IIS 屏幕,其中显示了有关该服务的一些基本信息。这意味着 Web 服务在指定的地址(端点)处于活动状态并运行。

我寻找了这个例外,但没有人有这些特点......通常涉及更详细和复杂的上下文。

怎么办?

还有一件事......

您可能想知道为什么我不使用服务引用...因为我不想。这是有原因的。这里的重点是 GetChannel 方法到目前为止一直对我有用......不明白为什么我现在有问题......

究竟应该是什么问题?不能超时真的不要相信这一点,它是一种简单的方法,在许多可能的方式中最快。很奇怪……真的。

【问题讨论】:

  • 脱离上下文的快速问题 --> 您是如何设法在客户端程序中获取 EchoService 类引用的?

标签: c# .net wcf web-services iis


【解决方案1】:

看起来您需要向控制台应用程序添加服务引用并使用代理对象,而不是您正在使用的实际服务类。您正在将服务用作客户端。而不是通过将服务引用添加到客户端项目时创建的自动生成的代理类调用服务。

【讨论】:

  • 代理的这个东西是我不太喜欢的东西...... GetChannel 的东西是我以前尝试过的东西并且一直有效......我不明白为什么现在它不起作用...... .
  • 嗯,您正在显式创建服务实例并尝试调用它。它的托管方式与您的示例描述的方式不同。您仍然可以在代理上使用 GetChannel 方法。
  • 对不起,我不明白您所说的“它不是按照您的示例描述的方式托管”的意思。请不要认为我傲慢,如果我现在有问题是因为我犯了一些错误......通过这种方法,我可以简单地获取我的服务实例,该实例由一个对象表示,该对象作为代表接口的接口返回合同。 getchannel 的东西将简单地创建端点并返回它。所以我连接到我的网络服务。我也知道这是通过代理完成的,但是我想手动完成,仅此而已...
  • 我很可能弄错了。现在还早,我不是 WCF 专家,只是看起来很奇怪而已。无意冒犯。
【解决方案2】:

问题与DataContract 相关。在我用作传递给服务方法的消息的一个类中,我有一个属性写错,导致序列化程序经历循环......这导致StackOverflow Exception 导致序列化程序变得狂暴并且连接被关闭.

我认为问题与数据无关,因此没有提供代码。抱歉打扰各位了。至少我的问题可以提供一些关于 DataContracts 中错误的有用信息,但通过查看异常描述无法真正掌握这些信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 2018-03-23
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多