using AD.SocketForm.Model;
using NLog;
using System;
using System.Net.Sockets;
using System.Threading; namespace AD.SocketForm.Service
{
/// <summary>
/// Socket连接类-可指定超时时间
/// 参考网址://www.cnblogs.com/weidagang2046/archive/2009/02/07/1385977.html
/// </summary>
public class SocketNewService
{
private Logger _logger = LogManager.GetCurrentClassLogger(); /// <summary>
/// 连接socket
/// </summary>
/// <param name="model"></param>
/// <param name="timeout">单位:毫秒</param>
/// <returns></returns>
public Socket Create(HubModel model, int timeout)
{
var isConnected = false;
var manualResetEvent = new ManualResetEvent(false);
var tcpClient = new TcpClient(); #region 异步方法委托
Action<IAsyncResult> 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;
}
} /// <summary>
/// 关闭socket
/// </summary>
/// <param name="socket"></param>
public void Close(Socket socket)
{
if (socket != null)
{
socket.Close();
socket = null;
}
} /// <summary>
/// 判断Socket是否已连接
/// </summary>
/// <param name="socket"></param>
/// <returns></returns>
public bool IsConnected(Socket socket)
{
if (socket == null || socket.Connected == false)
{
return false;
} bool blockingState = socket.Blocking;
try
{
byte[] tmp = new byte[];
socket.Blocking = false;
socket.Send(tmp, , );
return true;
}
catch (SocketException e)
{
// 产生 10035 == WSAEWOULDBLOCK 错误,说明被阻止了,但是还是连接的
if (e.NativeErrorCode.Equals())
{
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连接辅助类-可指定超时时间的更多相关文章

  1. c# 创建socket连接辅助类

    using AD.SocketForm.Model; using NLog; using System; using System.Net; using System.Net.Sockets; nam ...

  2. Socket超时时间设置

    你知道在 Java 中怎么对 Socket 设置超时时间吗?他们的区别是什么?想一想和女朋友打电话的场景就知道了,如果实在想不到,那我们就一起来来看一下是咋回事吧 设置方式 主要有以下两种方式,我们来 ...

  3. Http和Socket连接区别

    相信不少初学手机联网开发的朋友都想知道Http与Socket连接究竟有什么区别,希望通过自己的浅显理解能对初学者有所帮助. 1.TCP连接 要想明白Socket连接,先要明白TCP连接.手机能够使用联 ...

  4. Http、tcp、Socket连接区别

    转自Http.tcp.Socket连接区别 相信不少初学手机联网开发的朋友都想知道Http与Socket连接究竟有什么区别,希望通过自己的浅显理解能对初学者有所帮助. 1.TCP连接 要想明白Sock ...

  5. Http和Socket连接的区别

    Http和Socket连接区别 相信不少初学手机联网开发的朋友都想知道Http与Socket连接究竟有什么区别,希望通过自己的浅显理解能对初学者有所帮助. 1.TCP连接 要想明白Socket连接,先 ...

  6. Http和Socket连接

    转自http://hi.baidu.com/%D2%B9%D1%A9%B3%E6/blog/item/d6a72d2bbf467cf2e7cd406d.html 相信不少初学手机联网开发的朋友都想知道 ...

  7. TCP连接、Http连接与Socket连接

    1.TCP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上. ...

  8. Socket设置超时时间

    主要有以下两种方式,我们来看一下方式1: Socket s=new Socket(); s.connect(new InetSocketAddress(host,port),10000); 方式2: ...

  9. timeout Timeout时间已到.在操作完成之前超时时间已过或服务器未响应

    Timeout时间已到.在操作完成之前超时时间已过或服务器未响应 问题 在使用asp.net开发的应用程序查询数据的时候,遇到页面请求时间过长且返回"Timeout时间已到.在操作完成之间超 ...

随机推荐

  1. C#工作常用关键字

    1.throw //抛出throw new Exception("获取数据失败") //抛出异常 2.Ticks //long类型的数,表示时间,一个以0.1纳秒为单位的时间戳,/ ...

  2. C#/.Net操作MongoDBHelper类

    先 NuGet两个程序集 1:MongoDB.Driver.   2:MongoDB.Bson namespace ConsoleApp1{ /// <summary> /// Mongo ...

  3. Java内功心法,创建型设计模式包括哪些

    1. 单例(Singleton) Intent 确保一个类只有一个实例,并提供该实例的全局访问点. Class Diagram 使用一个私有构造函数.一个私有静态变量以及一个公有静态函数来实现. 私有 ...

  4. Elasticsearch的快照备份

    该文档适用于备份使用NAS的仓库类型.所有Elasticsearch集群中的服务通过挂载NAS目录来存放备份快照数据. 1.创建备份仓库 创建一个仓库名称:backup curl -H "C ...

  5. 目标检测论文解读13——FPN

    引言 对于小目标通常需要用到多尺度检测,作者提出的FPN是一种快速且效果好的多尺度检测方法. 方法 a,b,c是之前的方法,其中a,c用到了多尺度检测的思想,但他们都存在明显的缺点. a方法:把每图片 ...

  6. dapi 基于Django的轻量级测试平台四 任务设置

    QQ群: GitHub:https://github.com/yjlch1016/dapi 一.间隔时间: 二.定时时间: 三.任务设置: 四.任务结果:

  7. HDU5126 stars(cdq分治)

    传送门 题意: 先有两种操作,插入和查询,插入操作则插入一个点\((x,y,z)\),查询操作给出两个点\((x_1,y_1,z_1),(x_2,y_2,z_2)\),回答满足\(x_1\leq x\ ...

  8. 201871010128-杨丽霞《面向对象程序设计(java)》第二周学习总结

    201871010128-杨丽霞<面向对象程序设计(java)>第二周学习总结 项目 内容 这个作业属于哪个课程 <https://www.cnblogs.com/nwnu-daiz ...

  9. 海康SDK JAVA版本调用步骤及问题介绍

    一.前言 本文为海康SDK JAVA版本Demo的介绍,采用Eclipse运行,以及一些问题记录. 海康SDK版本:SDK_Win32 Eclipse版本:Mars2.0 JDK版本:1.8.0_15 ...

  10. 架构篇 | 带你轻松玩转 LAMP 网站架构平台(一)

    作者 | JackTian 微信公众号 | 杰哥的IT之旅(ID:Jake_Internet) 转载请联系授权(微信ID:Hc220066)备注:来自博客园 1.什么是 LAMP 架构? LAMP 架 ...