c# 创建socket连接辅助类-可指定超时时间
标签:log dag ORC lse ogg 连接 out ntc hub
using AD.SocketForm.Model;
using NLog;
using System;
using System.Net.Sockets;
using System.Threading;
namespace AD.SocketForm.Service
{
///
/// Socket连接类-可指定超时时间
/// 参考网址://www.cnblogs.com/weidagang2046/archive/2009/02/07/1385977.html
///
public class SocketNewService
{
private Logger _logger = LogManager.GetCurrentClassLogger();
///
/// 连接socket
///
///
/// 单位:毫秒
///
public Socket Create(HubModel model, int timeout)
{
var isConnected = false;
var manualResetEvent = new ManualResetEvent(false);
var tcpClient = new TcpClient();
#region 异步方法委托
Action action = (asyncresult) =>
{
try
{
TcpClient tcpclient = asyncresult.AsyncState as TcpClient;
if (tcpclient.Client != null)
{
tcpclient.EndConnect(asyncresult);
isConnected = true;
}
//Thread.Sleep(1000);
}
catch (Exception ex)
{
_logger.Error(string.Format("获取socket异常,message:{0},stacktrace:{1}", ex.Message, ex.StackTrace));
isConnected = false;
}
finally
{
manualResetEvent.Set();
}
};
#endregion
tcpClient.BeginConnect(model.IP, model.Port, new AsyncCallback(action), tcpClient);
//判断在指定的时间以内是否收到释放锁的通知
if (manualResetEvent.WaitOne(timeout, false))
{
//Console.WriteLine("连接成功");
if (isConnected)
{
return tcpClient.Client;
}
else
{
return null;
}
}
else
{
//Console.WriteLine("超时");
tcpClient.Close();
return null;
}
}
///
/// 关闭socket
///
///
public void Close(Socket socket)
{
if (socket != null)
{
socket.Close();
socket = null;
}
}
///
/// 判断Socket是否已连接
///
///
///
public bool IsConnected(Socket socket)
{
if (socket == null || socket.Connected == false)
{
return false;
}
bool blockingState = socket.Blocking;
try
{
byte[] tmp = new byte[1];
socket.Blocking = false;
socket.Send(tmp, 0, 0);
return true;
}
catch (SocketException e)
{
// 产生 10035 == WSAEWOULDBLOCK 错误,说明被阻止了,但是还是连接的
if (e.NativeErrorCode.Equals(10035))
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
_logger.Error(string.Format("检查Socket是否可连接时异常,message:{0},stacktrace:{1}", ex.Message, ex.StackTrace));
return false;
}
finally
{
socket.Blocking = blockingState; // 恢复状态
}
}
}
}
主要是通过两点:
1、通过if (manualResetEvent.WaitOne(timeout, false))来处理。它的作用是:阻止当前线程N毫秒,期间如果有调用manualResetEvent.Set()立即取消当前线程的阻塞,并且返回true;如果没有调用,时间到了后依然取消当前线程的阻塞,但是返回false。
2、通过tcpClient.BeginConnect(model.IP, model.Port, new AsyncCallback(action), tcpClient)建立tcp连接。这句话的意思是以异步的方式建立tcp连接,成功之后调用指定的回调方法。即new AsyncCallback(action)。
另外,这个类把回调方法写在了Create方法里面,原因是方便处理isConnected的状态,无需考虑线程同步。因为这个辅助类实例化后,是被驻留在内存里面的,有可能会被多次使用。为了线程安全,所以写在了里面。
c# 创建socket连接辅助类-可指定超时时间
标签:log dag ORC lse ogg 连接 out ntc hub
原文地址:https://www.cnblogs.com/subendong/p/11822937.html
评论