C# Socket连接请求超时机制
作者:RazanPaul
译者:Todd Wei
原文:http://www.codeproject.com/KB/IP/TimeOutSocket.aspx
介绍
您可能注意到了,.Net的System.Net.Sockets.TcpClient和System.Net.Sockets.Socket都没有直接为Connect/BeginConnect提供超时控制机制。因此,当服务器未处于监听状态,或者发生网络故障时,客户端连接请求会被迫等待很长一段时间,直到抛出异常。默认的等待时间长达20~30s。.Net Socket库的SocketOptionName.SendTimeout提供了控制发送数据的超时时间,但并非本文讨论的连接请求的超时时间。
背景
这个问题最初源于我的某个项目,在解决以后,我曾将关键代码发表在自己的博客上。我注意到不少人对此表示感谢,所以我想这是一个常见的问题,或许很多人都需要解决它。
实现
下面是实现的关键代码:
class TimeOutSocket
{
private static bool IsConnectionSuccessful = false;
private static Exception socketexception;
private static ManualResetEvent TimeoutObject = new ManualResetEvent(false); public static TcpClient Connect(IPEndPoint remoteEndPoint, int timeoutMSec)
{
TimeoutObject.Reset();
socketexception = null; string serverip = Convert.ToString(remoteEndPoint.Address);
int serverport = remoteEndPoint.Port;
TcpClient tcpclient = new TcpClient();
tcpclient.BeginConnect(serverip, serverport,
new AsyncCallback(CallBackMethod), tcpclient); if (TimeoutObject.WaitOne(timeoutMSec, false))
{
if (IsConnectionSuccessful)
{
return tcpclient;
}
else
{
throw socketexception;
}
}
else
{
tcpclient.Close();
throw new TimeoutException("TimeOut Exception");
}
}
private static void CallBackMethod(IAsyncResult asyncresult)
{
try
{
IsConnectionSuccessful = false;
TcpClient tcpclient = asyncresult.AsyncState as TcpClient;
if (tcpclient.Client != null)
{
tcpclient.EndConnect(asyncresult);
IsConnectionSuccessful = true;
}
}
catch (Exception ex)
{
IsConnectionSuccessful = false;
socketexception = ex;
}
finally
{
TimeoutObject.Set();
}
}
}
这里,ManualResetEvent的WaitOne(TimeSpan, Boolean)起到了主要的作用。它将阻止当前线程,直到ManualResetEvent对象被Set或者超过timeout时间。上面的代码中,调用BeginConnect后通过WaitOne方法阻止当前线程,如果在timeoutMSec时间内连接成功,将在CallBackMethod回调中调用TimeoutObject.Set,解除被阻塞的连接线程并返回;否则,连接线程会在等待超时后,主动关闭连接并抛出TimeoutException。
总结
虽然实现非常简单,但或许很多人都需要连接请求超时机制,如果有任何问题,我会尽力为您解答。
C# Socket连接请求超时机制的更多相关文章
- C# Socket.Connect连接请求超时机制
介绍 您可能注意到了,.Net的System.Net.Sockets.TcpClient和System.Net.Sockets.Socket都没有直接为Connect/BeginConnect提供超时 ...
- 异步和同步http请求超时机制
异步超时设置: 例子: Example: do a simple HTTP GET request for http://www.nethype.de/ and print the response ...
- socket测试远程地址能否连接并为连接设置超时
public class TestConnect { string hostIp = ""; ; public string recMsg = ""; Sock ...
- socket测试远程地址能否连接并为连接设置超时(转)
public class TestConnect { string hostIp = ""; int port = 3314; public string recMsg = & ...
- 从报错“无效操作,连接被关闭”探究Transaction的Timeout超时机制
1.报错如下:Invalid Operation the connection is closed,无效操作,连接被关闭.这个错误是并不是每次都报,只有在复杂操作.大事务的情况下才偶然报出来. sta ...
- C# Socket连接超时设置
问题描述: 对于C# Socket没有超时设置的选项,默认情况下进行Socket连接,返回连接失败需要20-30s时间,严重影响用户体验 问题解决: Socket服务器端: Socke ...
- 一个Socket连接管理池(心跳机制)
一个Socket连接管理池(心跳机制) http://cuisuqiang.iteye.com/blog/1489661
- ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用!因此,ES transport client可以同步调用也可以异步(不过底层的socket必然是异步实现)
ES transport client底层是netty实现,netty本质上是异步方式,但是netty自身可以使用sync或者await(future超时机制)来实现类似同步调用! 因此,ES tra ...
- c# 创建socket连接辅助类-可指定超时时间
using AD.SocketForm.Model; using NLog; using System; using System.Net.Sockets; using System.Threadin ...
随机推荐
- 控制HTML元素的显示与隐藏——display和visibility
有些时候我们需要根据某些条件来控制Web页面中的HTML元素显示还是隐藏,可以通过display或visibility来实现.通过下面的例子了解display和visibility的区别,简单的例子代 ...
- Java多线程之锁
首先是synchronized 关键字 他可以用于声明方法,也可以用于申明代码块.我们看看三个例子: public class SynchronizedDemo1 { public synchroni ...
- SQL---------表的约束
表的约束 防止同一条数据完全重复:主键约束(primary key)唯一键约束(unique),自增长: 防止数据为空: 非空约束(not noll),默认值: 防止乱填数据: 外键, 定义数据类型, ...
- WPF 之 数据绑定
数据绑定需要: 后台必须要有与控件对应的类和相关的属性 在后台new 一个类的对象 在后台把控件的数据上下文设置为该对象. 在XAML中把要绑定的控件中Text = "{Bindi ...
- CSS3 照片墙
HTML <body> <h2>照片墙制作</h2> <div class="container"> <img class=& ...
- php学习笔记6--php中的文件包含 include,require,include_once,require_once
php中的文件包含 include,require,include_once,require_once 文件包含:是指将一个文件的内容包含进另外一个文件,有利于代码的复用等.php中文件包含指令有4个 ...
- 关于SVN下载代码和Android Studio里面导入别人代码build tools不一致问题总结
项目build tools的sdk我没有 网络问题没法下载. 解决问题 方法 1.下载对应的SDK.需要VPN,或者FQ 2.将bulid.gradle的内容用下面的内容替换 // Top-level ...
- 关于java中普通代码块、构造代码块与静态代码块
1.普通代码块 public static void main(String[] args) { /*普通代码块: *直接定义在在方法或语句中出现”{普通代码的执行语句}“的就称为普通代码块. *普通 ...
- 20150320--安全性,Membership类
安全性--验证与授权,成员资格与角色. 一.成员资格与角色, 第一步:注册数据库,在VS中运行dos命令窗口中,输入:aspnet_regsql,建立数据库表. 如何启动VS的dos命令窗口,在 . ...
- 构造高度自适应的textarea
高度自适应的textarea,这个需求还是比较常见的,随着用户的输入textarea的高度自动变化,这样输入较少的时候可以节省空间,输入多的时候可以不出现滚动条,让内容尽可能的展现在用户的视线内. 可 ...