gpt4 book ai didi

c# - ASP.NET WebMethod 和半开连接

转载 作者:可可西里 更新时间:2023-11-01 02:32:43 25 4
gpt4 key购买 nike

考虑一些客户端调用 WebMethod 并且在建立连接后主机进程崩溃并且连接变为半打开的情况。 ASP.NET WebMethod 代理会自动检测到它吗?

我们假设 WebMethod 超时设置为无穷大或某个较长的时间。是否仅在 TCP keep-alive 数据包发送时检测到连接错误(默认情况下在 Windows 上空闲 2 小时后)?

[WebService(Namespace = "http://www.example.com/TestService/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class TestService : System.Web.Services.WebService
{
[WebMethod]
public void DoLongWork()
{
// long work here
}
}

网络引用代理调用:

public void ServiceClient()
{
var serviceProxy = new MyNamespace.TestService();
// serviceProxy.Url = ...
serviceProxy.Timeout = -1; // do not use timeout

// will it wait for 2 hours (when TCP keep-alive will be sent) if connection was lost after handshake?
serviceProxy.DoLongWork();
}

更新。

我已经尝试了多种方案,这里是我使用 Wireshark 了解幕后情况的结果。

  1. 停止通过 IIS 管理器托管 Web 服务器 (IIS) 或终止主机进程 (w3wp.exe): enter image description here

在这两种情况下,客户端都通过发送 TCP RST 标志得到通知。似乎 Windows 负责关闭崩溃/终止进程的套接字。在 .NET 中,将抛出 System.Net.WebException:

Unhandled Exception: System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)   --- End of inner exception stack trace ---   at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)   at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)   at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)   --- End of inner exception stack trace ---   at System.Web.Services.Protocols.WebClientProtocol.GetWebResponse(WebRequest request)   at System.Web.Services.Protocols.HttpWebClientProtocol.GetWebResponse(WebRequest request)   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)   at WebMethodAndTCPHalfOpenTest.TestWebReference.TestService.DoLongWork(Int32 sec)   at WebMethodAndTCPHalfOpenTest.Program.Main(String[] args) 
  1. 在(到主机的)连接丢失后终止主机进程,因此 TCP RST 无法到达客户端:这里的结果对我来说非常纠结,因为2.5 小时后未检测到断开的连接(半开)并且客户端仍然认为底层 TCP 连接是事件的(相同6 小时后的情况)。这里是 Sysinternals TCPView 的输出:
TCPView v3.01 - TCP/UDP endpoint viewer Copyright (C) 1998-2010Mark Russinovich and Bryce Cogswell Sysinternals -www.sysinternals.com[TCP] WebMethodAndTCPHalfOpenTest.exe        PID:    8180        State:  ESTABLISHED        Local:  192.168.1.2        Remote: 5.167.159.81
Windows Version: Microsoft Windows [Version 6.1.7601]

Wireshark 输出:

after 2.5 hours of half-open connection

我检查过 KeepAliveTime我的系统上的注册表设置在这里:

HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
它丢失了,所以应该使用默认的 2 小时 (?)。

谁能解释第二点描述的结果?为什么没有发送 TCP keepalive?代理是否为底层套接字 ( https://msdn.microsoft.com/en-us/library/windows/desktop/ee470551(v=vs.85).aspx ) 明确设置了不同的保持事件行为?

最佳答案

看起来 keep alive 并没有得到保证,因为 Windows 中的设置可能会搞砸(没有注册表值不是全部)。

据此: Windows TCP socket has SO_KEEPALIVE enabled by default?

看起来您不应该依赖此行为并设置超时。如果您使用的是 soap 请求,您始终可以调用异步请求,然后根据客户端可配置值等待请求,并对超时进行良好的逻辑处理。

关于c# - ASP.NET WebMethod 和半开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28331558/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com