C# Socket连接请求超时机制实现代码分享
.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 tryconnect(ipendpoint remoteendpoint, int timeoutmilisecond)
{
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(timeoutmilisecond, 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();
}
}
}