- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试在异步 HTTP 客户端中重用套接字,但我无法第二次连接到主机。我基本上将我的异步 HTTP 客户端视为具有以下状态的状态机:
在连接状态我调用BeginConnect
:
private void BeginConnect()
{
lock (_sync) // re-entrant lock
{
IPAddress[] addersses = Dns.GetHostEntry(_asyncTask.Host).AddressList;
// Connect to any available address
IAsyncResult result = _reusableSocket.BeginConnect(addersses, _asyncTask.Port, new AsyncCallback(ConnectCallback), null);
}
}
一旦成功建立连接,回调方法将状态更改为正在发送
:
private void ConnectCallback(IAsyncResult result)
{
lock (_sync) // re-entrant lock
{
try
{
_reusableSocket.EndConnect(result);
ChangeState(EClientState.Sending);
}
catch (SocketException e)
{
Console.WriteLine("Can't connect to: " + _asyncTask.Host);
Console.WriteLine("SocketException: {0} Error Code: {1}", e.Message, e.NativeErrorCode);
ThreadPool.QueueUserWorkItem(o =>
{
// An attempt was made to get the page so perform a callback
ChangeState(EClientState.Failed);
});
}
}
}
在清理过程中,我关闭
套接字并使用重用标志断开
:
private void CleanUp()
{
lock (_sync) // re-entrant lock
{
// Perform cleanup
if (_reusableSocket.Connected)
{
_reusableSocket.Shutdown(SocketShutdown.Both);
_reusableSocket.Disconnect(true);
}
ChangeState(EClientState.Available);
}
}
对 BeginConnect
的后续调用导致超时和异常:
SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond XX.XXX.XX.XX:80
Error Code: 10060
这是状态轨迹:
Initializing...
Change State: Connecting
Change State: Sending
Change State: Receiving
Change State: CleanUp
Callback: Received data from client 0 // <--- Received the first data
Change State: Available
Change State: Connecting // <--- Timeout when I try to reuse the socket to connect to a different endpoint
我必须做什么才能重用套接字连接到不同的主机?
注意:我
没有
尝试重新连接到同一个主机,但
我假设
发生了同样的事情(即连接失败)。
更新
我在 documentation of BeginConnect 中找到了以下注释:
If this socket has previously been disconnected, then BeginConnect must be called on a thread that will not exit until the operation is complete. This is a limitation of the underlying provider. Also the EndPoint that is used must be different.
我开始怀疑我的问题是否与此有关...我正在连接到不同的端点,但它们是什么意思,我们从中调用 BeginConnect 的线程在操作完成之前不得退出?
2.0 更新:
我问了一个related question我尝试使用“Async family”调用而不是“Begin family”调用,但我遇到了同样的问题!!!
最佳答案
我评论了这个问题:what is benefit from socket reuse in C# about socket reuse using Disconnect(true)/DisconnectEx()
这可能对你有帮助。
我个人认为这是对客户端代码的过度优化。
重新更新 1 到您的问题;不,如果是这种情况,你会得到一个 AbortedOperation 异常(见这里:VB.NET 3.5 SocketException on deployment but not on development machine),如果你在 Vista 或更高版本上运行,文档是错误的,因为它不强制执行“线程必须存在,直到重叠 I/O 完成”以前的操作系统执行的规则。
正如我在对相关问题的回复中所说的那样;使用此功能建立出站连接毫无意义。它很可能最初被添加到 Winsock API 以支持入站连接上 AcceptEx()
的套接字重用,其中,在使用 TransmitFile()
的非常繁忙的 Web 服务器上> 将文件发送给客户端(这是为重用断开连接似乎起源的地方)。文档指出它不能很好地与 TIME_WAIT
一起使用,因此将它用于您启动主动关闭的连接(从而将套接字置于 TIME_WAIT
中,请参阅 here )真的没有意义。
您能解释一下为什么您认为这种微优化在您的案例中实际上是必要的吗?
关于c# - 重用异步套接字 : subsequent connect attempts fail,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5762276/
尝试从对话框中的 EditText 获取 Edit Text 的值,但一次又一次地出现此错误 Attempt to invoke virtual method 'android.text.Editab
最近尝试了一下最新的Laravel(6.4)。正在尝试实现基于 API 的简单登录功能。没有使用 Passport 或 Tymon 的 JWT 等任何软件包。我使用了非常基本的身份验证(只需在用户表中
最近尝试了一下最新的Laravel(6.4)。正在尝试实现基于 API 的简单登录功能。没有使用 Passport 或 Tymon 的 JWT 等任何软件包。我使用了非常基本的身份验证(只需在用户表中
我在我的 PC 上运行 cifar10 网络,在完成训练和运行评估脚本后出现以下错误: 2016-06-01 14:37:14.238317: precision @ 1 = 0.000 Traceb
我正在使用 ng2-toastr 并收到以下错误 https://www.npmjs.com/package/ng2-toastr Attempt to use a destroyed view: d
env file:环境文件: APP_ENV=localAPP_DEBUG=trueAPP_KEY= ...........DB_HOST=srv3.linuxisrael.co.ilDB_D
当我登录管理员时,我正在尝试对 api 进行多重保护身份验证,我得到了跟随错误 BadMethodCallException Method Illuminate\Auth\Req uestGuard:
我开始在 Lua 中进行编程,并在运行脚本时出现此错误: attempt to index upvalue 'base' (a function value) 这可能是因为我还没有掌握一些非常基本的东
我试图在 Oozie 工作流中聚合一些数据。但是聚合步骤失败。 我在日志中发现了两个兴趣点:第一个是一个似乎重复出现的错误(?): 容器完成后,它会被杀死,但会以非零退出代码 143 退出。 它完成了
我的问题是当我调用函数时: [self performSegueWithIdentifier: @"FinalPlayPT" sender: self]; 它有效,但我有这个警告: Warning:
项目背景 项目整体采用的是springboot+mybatis 方式。有一次做数据查询的时候。console突然报:DataIntegrityViolationException: Error att
我在使用 Jobs 发送电子邮件的 Ubuntu Server 上设置了 Laravel 项目。 下面是我在 中的 laravel-worker 文件/etc/supervisor/laravel-w
尝试运行我的 React 应用程序时收到以下错误: ./src/components/App/App.js Attempted import error: 'combineReducers' is n
我的编码功能是这样的: fn encode_login(packet: &str) { let bytes = packet.as_bytes(); for (i, &element)
如果一个版本号大于另一个版本号,我的 msbuild 需要采取有条件的操作。我尝试像下面这样编写代码,但发现出现错误(也在下面)。我哪里出错了?
我是 Lua 的新手,并试图让事情在我的脑海中进行排序。我试过这个代码: function newCarousel(images) local slideToImage = function(
我正在使用 entrust用于在 Laravel 5.3 中管理基于角色的权限,并自然地为不同的用户类型使用手动/自定义登录。 Auth::attempt()可以吗?处理外表关系?基本上,我想做这样的
我谷歌了一遍又一遍,但没有对我有用的信息。 情况是这样的:1.产品有 active 。2.我通过测试账号来测试我的apk。3.我已经上传了一整天的apk。 但是当我想为应用程序中的项目付款时,goog
我正在尝试使用 groovy 解析日期字符串,但遇到了问题。这是字符串的样子和不起作用的逻辑。 def dateString = "2017-01-01T12:00:00Z" def date = D
我正在使用 ParseFacebookUtils 从 Facebook 登录我的应用。 LoginActivity 的 onCreate: protected void onCreate(Bundle
我是一名优秀的程序员,十分优秀!