介绍开源的.net通信框架NetworkComms框架 源码分析(二十二 )TCPConnectionStatic
原文网址: http://www.cnblogs.com/csdev
Networkcomms 是一款C# 语言编写的TCP/UDP通信框架 作者是英国人 以前是收费的 目前作者已经开源 许可是:Apache License v2
开源地址是:https://github.com/MarcFletcher/NetworkComms.Net
public sealed partial class TCPConnection : IPConnection
{
/// <summary>
/// By default usage of <see href="http://en.wikipedia.org/wiki/Nagle's_algorithm">Nagle's algorithm</see> during TCP exchanges is disabled for performance reasons. If you wish it to be used for newly established connections set this property to true.
/// 默认 不启用Nagle算法
/// Nagle算法处于禁用状态时 TCP连接上一旦有数据将会被立即发送 【默认状态】
/// Nagle算法处于启用状态时 系统等待直到缓冲器的数据足够多才一起发送
/// </summary>
public static bool EnableNagleAlgorithmForNewConnections { get; set; }
#region GetConnection
/// <summary>
/// Create a <see cref="TCPConnection"/> with the provided connectionInfo. If there is an existing connection that will be returned instead.
/// If a new connection is created it will be registered with NetworkComms and can be retrieved using <see cref="NetworkComms.GetExistingConnection(ConnectionInfo)"/> and overrides.
/// 根据连接信息 创建一个TCP连接 如果有已经创建的连接则直接返回这个连接
/// 如果一个新的连接创建后 将会在NetworkComms静态类中进行注册 并且能够以 NetworkComms.GetExistingConnection(连接信息类)的方式获取到
/// </summary>
/// <param name="connectionInfo">连接信息类 ConnectionInfo to be used to create connection</param>
/// <param name="establishIfRequired">如果需要则创建TCP连接 If true will establish the TCP connection with the remote end point before returning</param>
/// <returns>Returns a <see cref="TCPConnection"/></returns>
public static TCPConnection GetConnection(ConnectionInfo connectionInfo, bool establishIfRequired = true)
{
//Added conditional compilation so that GetConnection method usage is not ambiguous.
//附加条件编译 使得GetConnection方法的调用比较清晰
SendReceiveOptions options = null;
#if WINDOWS_PHONE || NETFX_CORE
StreamSocket socket = null;
return GetConnection(connectionInfo, options, socket, establishIfRequired);
#else
TcpClient tcpClient = null;
return GetConnection(connectionInfo, options, tcpClient, establishIfRequired);
#endif
}
/// <summary>
/// Create a TCP connection with the provided connectionInfo and sets the connection default SendReceiveOptions. If there is an existing connection that is returned instead.
/// If a new connection is created it will be registered with NetworkComms and can be retrieved using <see cref="NetworkComms.GetExistingConnection(ConnectionInfo)"/> and overrides.
/// 根据指定的 连接信息类 创建一个TCP连接 并且设置连接的默认 收发参数 如果连接已经存在则直接返回此已经存在的连接
/// 如果一个新的连接创建后 将会在NetworkComms静态类中进行注册 并且能够以 NetworkComms.GetExistingConnection(连接信息类)的方式获取到
/// </summary>
/// <param name="connectionInfo">连接信息 ConnectionInfo to be used to create connection</param>
/// <param name="defaultSendReceiveOptions">默认收发参数 The SendReceiveOptions which will be set as this connections defaults</param>
/// <param name="establishIfRequired">如果需要则创建TCP连接 If true will establish the TCP connection with the remote end point before returning</param>
/// <returns>Returns a <see cref="TCPConnection"/></returns>
public static TCPConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, bool establishIfRequired = true)
{
//Added conditional compilation so that GetConnection method usage is not ambiguous.
//附加条件编译 使得GetConnection方法的调用比较清晰
#if WINDOWS_PHONE || NETFX_CORE
StreamSocket socket = null;
return GetConnection(connectionInfo, defaultSendReceiveOptions, socket, establishIfRequired);
#else
TcpClient tcpClient = null;
return GetConnection(connectionInfo, defaultSendReceiveOptions, tcpClient, establishIfRequired);
#endif
}
#if !WINDOWS_PHONE && !NETFX_CORE
/// <summary>
/// Create a TCP connection with the provided connectionInfo and sets the connection default SendReceiveOptions. If there is an existing connection that is returned instead.
/// If a new connection is created it will be registered with NetworkComms and can be retrieved using <see cref="NetworkComms.GetExistingConnection(ConnectionInfo)"/> and overrides.
/// 根据指定的 连接信息类 创建一个TCP连接 并且设置连接的默认 收发参数 如果连接已经存在则直接返回此已经存在的连接
/// 如果一个新的连接创建后 将会在NetworkComms静态类中进行注册 并且能够以 NetworkComms.GetExistingConnection(连接信息类)的方式获取到
/// </summary>
/// <param name="connectionInfo">连接信息 ConnectionInfo to be used to create connection</param>
/// <param name="defaultSendReceiveOptions">默认收发参数 The SendReceiveOptions which will be set as this connections defaults</param>
/// <param name="sslOptions"> 安全套接层选项 SSLOptions to use with this connection</param>
/// <param name="establishIfRequired">如果需要则创建TCP连接 If true will establish the TCP connection with the remote end point before returning</param>
/// <returns>Returns a <see cref="TCPConnection"/></returns>
public static TCPConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, SSLOptions sslOptions, bool establishIfRequired = true)
{
return GetConnection(connectionInfo, defaultSendReceiveOptions, null, establishIfRequired, sslOptions);
}
#endif
#if WINDOWS_PHONE || NETFX_CORE
/// <summary>
/// Internal <see cref="TCPConnection"/> creation which hides the necessary internal calls
/// </summary>
/// <param name="connectionInfo">ConnectionInfo to be used to create connection</param>
/// <param name="defaultSendReceiveOptions">Connection default SendReceiveOptions</param>
/// <param name="socket">If this is an incoming connection we will already have access to the socket, otherwise use null</param>
/// <param name="establishIfRequired">Establish during create if true</param>
/// <returns>An existing connection or a new one</returns>
internal static TCPConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, StreamSocket socket, bool establishIfRequired)
#else
/// <summary>
/// Internal <see cref="TCPConnection"/> creation which hides the necessary internal calls
/// //内部的TCPConnection 创建 (隐藏了需要的内部调用)
/// </summary>
/// <param name="connectionInfo">连接信息 ConnectionInfo to be used to create connection</param>
/// <param name="defaultSendReceiveOptions">默认收发参数 Connection default SendReceiveOptions</param>
/// <param name="tcpClient">如果这是一个传入的连接 我们将可以TcpClient 否则为NULL 。*** If this is an incoming connection we will already have access to the tcpClient, otherwise use null</param>
/// <param name="establishIfRequired">如果需要则创建 Establish during create if true</param>
/// <param name="sslOptions">安全套接层选项 SSL options that will be used with this connection.</param>
/// <returns>返回TCP连接 An existing connection or a new one</returns>
internal static TCPConnection GetConnection(ConnectionInfo connectionInfo, SendReceiveOptions defaultSendReceiveOptions, TcpClient tcpClient, bool establishIfRequired, SSLOptions sslOptions = null)
#endif
{
connectionInfo.ConnectionType = ConnectionType.TCP;
//If we have a tcpClient at this stage we must be server side
#if WINDOWS_PHONE || NETFX_CORE
if (socket != null) connectionInfo.ServerSide = true;
#else
if (tcpClient != null) connectionInfo.ServerSide = true;
if (sslOptions == null) sslOptions = new SSLOptions();
#endif
//Set default connection options if none have been provided
//设置默认的收发参数 如果该参数还没有被设置
if (defaultSendReceiveOptions == null) defaultSendReceiveOptions = NetworkComms.DefaultSendReceiveOptions;
bool newConnection = false;
TCPConnection connection;
lock (NetworkComms.globalDictAndDelegateLocker)
{
List<Connection> existingConnections = NetworkComms.GetExistingConnection(connectionInfo.RemoteIPEndPoint, connectionInfo.LocalIPEndPoint, connectionInfo.ConnectionType, connectionInfo.ApplicationLayerProtocol);
//Check to see if a connection already exists, if it does return that connection, if not return a new one
//检查一个连接是否存在 如果存在则返回该连接 如果不存在则创建一个
)
{
if (NetworkComms.LoggingEnabled)
NetworkComms.Logger.Trace("Attempted to create new TCPConnection to connectionInfo='" + connectionInfo + "' but there is an existing connection. Existing connection will be returned instead.");
establishIfRequired = false;
connection = (TCPConnection)existingConnections[];
}
else
{
if (NetworkComms.LoggingEnabled)
NetworkComms.Logger.Trace("Creating new TCPConnection to connectionInfo='" + connectionInfo + "'." + (establishIfRequired ? " Connection will be established." : " Connection will not be established."));
if (connectionInfo.ConnectionState == ConnectionState.Establishing)
throw new ConnectionSetupException("Connection state for connection " + connectionInfo + " is marked as establishing. This should only be the case here due to a bug.");
//If an existing connection does not exist but the info we are using suggests it should we need to reset the info
//so that it can be reused correctly. This case generally happens when using Comms in the format
//TCPConnection.GetConnection(info).SendObject(packetType, objToSend);
//如果一个连接信息已经存在 重置连接信息
//此种情况可能在使用如下格式的调用方法中出现 TCPConnection.GetConnection(info).SendObject(packetType, objToSend);
if (connectionInfo.ConnectionState == ConnectionState.Established || connectionInfo.ConnectionState == ConnectionState.Shutdown)
connectionInfo.ResetConnectionInfo();
//We add a reference to networkComms for this connection within the constructor
//在构造函数中 我们添加一个连接类的引用到NetworkComms静态类的字典中
#if WINDOWS_PHONE || NETFX_CORE
connection = new TCPConnection(connectionInfo, defaultSendReceiveOptions, socket);
#else
connection = new TCPConnection(connectionInfo, defaultSendReceiveOptions, tcpClient, sslOptions);
#endif
newConnection = true;
}
}
if (newConnection && establishIfRequired) connection.EstablishConnection();
else if (!newConnection) connection.WaitForConnectionEstablish(NetworkComms.ConnectionEstablishTimeoutMS);
if (!NetworkComms.commsShutdown) TriggerConnectionKeepAliveThread();
return connection;
}
#endregion
#region Depreciated 以下为不再使用的方法
/// <summary>
/// Accept new incoming TCP connections on all allowed IP's and Port's
/// </summary>
/// <param name="useRandomPortFailOver">If true and the default local port is not available will select one at random. If false and a port is unavailable listening will not be enabled on that adaptor</param>
[Obsolete("Depreciated, please use Connection.StartListening.")]
public static void StartListening(bool useRandomPortFailOver = false)
{
List<IPAddress> localIPs = HostInfo.IP.FilteredLocalAddresses();
try
{
foreach (IPAddress ip in localIPs)
{
try
{
StartListening(), useRandomPortFailOver);
}
catch (CommsSetupShutdownException)
{
}
}
}
catch (Exception)
{
//If there is an exception here we remove any added listeners and then rethrow
Shutdown();
throw;
}
}
/// <summary>
/// Accept new TCP connections on specified list of <see cref="IPEndPoint"/>
/// </summary>
/// <param name="localEndPoints">The localEndPoints to listen for connections on</param>
/// <param name="useRandomPortFailOver">If true and the requested local port is not available on a given IPEndPoint will select one at random. If false and a port is unavailable will throw <see cref="CommsSetupShutdownException"/></param>
[Obsolete("Depreciated, please use Connection.StartListening.")]
public static void StartListening(List<IPEndPoint> localEndPoints, bool useRandomPortFailOver = true)
{
if (localEndPoints == null) throw new ArgumentNullException("localEndPoints", "Provided List<IPEndPoint> cannot be null.");
try
{
foreach (var endPoint in localEndPoints)
{
if (endPoint.Address == IPAddress.Any)
throw new NotSupportedException("IPAddress.Any may not be specified for this depreciated method. Please use Connection.StartListening() instead.");
StartListening(endPoint, useRandomPortFailOver);
}
}
catch (Exception)
{
//If there is an exception here we remove any added listeners and then rethrow
Shutdown();
throw;
}
}
/// <summary>
/// Accept new incoming TCP connections on specified <see cref="IPEndPoint"/>
/// </summary>
/// <param name="newLocalEndPoint">The localEndPoint to listen for connections on.</param>
/// <param name="useRandomPortFailOver">If true and the requested local port is not available will select one at random. If false and a port is unavailable will throw <see cref="CommsSetupShutdownException"/></param>
/// <param name="allowDiscoverable">Determines if the newly created <see cref="ConnectionListenerBase"/> will be discoverable if <see cref="Tools.PeerDiscovery"/> is enabled.</param>
[Obsolete("Depreciated, please use Connection.StartListening.")]
public static void StartListening(IPEndPoint newLocalEndPoint, bool useRandomPortFailOver = true, bool allowDiscoverable = false)
{
if (newLocalEndPoint.Address == IPAddress.Any)
throw new NotSupportedException("IPAddress.Any may not be specified for this depreciated method. Please use Connection.StartListening() instead.");
TCPConnectionListener listener = new TCPConnectionListener(NetworkComms.DefaultSendReceiveOptions, ApplicationLayerProtocolStatus.Enabled, allowDiscoverable);
Connection.StartListening(listener, newLocalEndPoint, useRandomPortFailOver);
}
/// <summary>
/// Returns a list of <see cref="IPEndPoint"/> corresponding to all current TCP local listeners
/// </summary>
/// <returns>List of <see cref="IPEndPoint"/> corresponding to all current TCP local listeners</returns>
[Obsolete("Depreciated, please use Connection.ExistingLocalListenEndPoints.")]
public static List<IPEndPoint> ExistingLocalListenEndPoints()
{
List<IPEndPoint> result = new List<IPEndPoint>();
foreach (IPEndPoint endPoint in Connection.ExistingLocalListenEndPoints(ConnectionType.TCP))
result.Add(endPoint);
return result;
}
/// <summary>
/// Returns a list of <see cref="IPEndPoint"/> corresponding to a possible local listeners on the provided <see cref="IPAddress"/>. If not listening on provided <see cref="IPAddress"/> returns empty list.
/// </summary>
/// <param name="ipAddress">The <see cref="IPAddress"/> to match to a possible local listener</param>
/// <returns>If listener exists returns <see cref="IPAddress"/> otherwise null</returns>
[Obsolete("Depreciated, please use Connection.ExistingLocalListenEndPoints.")]
public static List<IPEndPoint> ExistingLocalListenEndPoints(IPAddress ipAddress)
{
List<IPEndPoint> result = new List<IPEndPoint>();
)))
result.Add(endPoint);
return result;
}
/// <summary>
/// Returns true if listening for new TCP connections.
/// </summary>
/// <returns>True if listening for new TCP connections.</returns>
[Obsolete("Depreciated, please use Connection.Listening.")]
public static bool Listening()
{
return Connection.Listening(ConnectionType.TCP);
}
#endregion
}
介绍开源的.net通信框架NetworkComms框架 源码分析(二十二 )TCPConnectionStatic的更多相关文章
- 介绍开源的.net通信框架NetworkComms框架 源码分析(十二)PriorityQueue
原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架 作者是英国人 以前是收费的 目前作者已经开源 许可是 ...
- DotNetty网络通信框架学习之源码分析
DotNetty网络通信框架学习之源码分析 有关DotNetty框架,网上的详细资料不是很多,有不多的几个博友做了简单的介绍,也没有做深入的探究,我也根据源码中提供的demo做一下记录,方便后期查阅. ...
- 深入理解分布式调度框架TBSchedule及源码分析
简介 由于最近工作比较忙,前前后后花了两个月的时间把TBSchedule的源码翻了个底朝天.关于TBSchedule的使用,网上也有很多参考资料,这里不做过多的阐述.本文着重介绍TBSchedule的 ...
- Android 图片加载框架Glide4.0源码完全解析(二)
写在之前 上一篇博文写的是Android 图片加载框架Glide4.0源码完全解析(一),主要分析了Glide4.0源码中的with方法和load方法,原本打算是一起发布的,但是由于into方法复杂性 ...
- 设计模式(十五)——命令模式(Spring框架的JdbcTemplate源码分析)
1 智能生活项目需求 看一个具体的需求 1) 我们买了一套智能家电,有照明灯.风扇.冰箱.洗衣机,我们只要在手机上安装 app 就可以控制对这些家电工作. 2) 这些智能家电来自不同的厂家,我们不想针 ...
- 设计模式(二十一)——解释器模式(Spring 框架中SpelExpressionParser源码分析)
1 四则运算问题 通过解释器模式来实现四则运算,如计算 a+b-c 的值,具体要求 1) 先输入表达式的形式,比如 a+b+c-d+e, 要求表达式的字母不能重复 2) 在分别输入 a ,b, c, ...
- $Django cbv源码分析 djangorestframework框架之APIView源码分析
1 CBV的源码分析 #视图 class login (View): pass #路由 url(r'^books/$', views.login.as_view()) #阅读源码: #左侧工程栏--- ...
- ④NuPlayer播放框架之Renderer源码分析
[时间:2016-11] [状态:Open] [关键词:android,nuplayer,开源播放器,播放框架,渲染器,render] 0 导读 之前我们分析了NuPlayer的实现代码,本文将重点聚 ...
- ⑤NuPlayer播放框架之GenericSource源码分析
[时间:2017-01] [状态:Open] [关键词:android,nuplayer,开源播放器,播放框架,GenericSource] 0 导读 GenericSource是NuPlayer:: ...
- ③NuPlayer播放框架之类NuPlayer源码分析
[时间:2016-10] [状态:Open] [关键词:android,nuplayer,开源播放器,播放框架] 0 引言 差不多一个月了,继续分析AOSP的播放框架的源码.这次我们需要深入分析的是N ...
随机推荐
- VM12.1.1 下载 序列号
VF5XA-FNDDJ-085GZ-4NXZ9-N20E6UC5MR-8NE16-H81WY-R7QGV-QG2D8ZG1WH-ATY96-H80QP-X7PEX-Y30V4AA3E0-0VDE1-0 ...
- 【解决】putty使用从AWS下载的private key登录失败
在AWS启动一个实例时如果创建并下载了一个KeyPair的私钥(*.pem),则可以此私钥作为Credentials通过putty远程登录到这个实例系统.但在实际操作中,用putty登录时会提示如下错 ...
- 第五届山东ACM大赛汇总
A.angry_birds_again_and_again 简单积分: http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem& ...
- 向架构师进军--->系统架构设计基础知识
如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 在讲解系统架构设计之前,有必要补充一下架构相关的概念,因此本博文主要讲述架构.架构师 ...
- review again and again
盲评结果出来了.然而对于我并没有太大的影响.从头到尾我没有紧张过,自然也不会有如释重负的感觉. 昨天说了事情要提前做准备.早上,到教研室挺早,review的时候,发现论文中一个关于目录的小问题,解决掉 ...
- Spring对 JDBC 的支持,JdbcTemplate类的使用
导包:spring框架的包 和 连接数据库连接池的c3p0包 连接mysql数据库的包; 在src目录下建立jdbc.properties文件:存放连接数据库的属性值 jdbc.user=root j ...
- git 查看远程分支、本地分支、删除本地分支【转】
1 查看远程分支 $ git branch -a * br-2.1.2.2 master remotes/origin/HEAD -> origin/master remotes/origin/ ...
- VS2013不显示最近打开文件
首先点击开始在左下角输入"regedit" 右击HKEY_CURRENT_USER,点击查找,输入NoRecentDocsHistory 在右边找到NoRecentDocsHist ...
- 湖人VS爵士!!科比4月14日最后一战,本赛季最高得分!狂得60分!!完美大逆转!!!
莫愁前路无知己,天下谁人不识君.科比,愿你如迈克尔·乔丹,仍然活跃在篮球界.退役不是结束,而是另一段人生的开始. 北京时间2016年4月14日,湖人101-96击败爵士,科比-布莱恩特告别战,20年职 ...
- for 小曦
安装GO 当前版本1.6.2 http://blog.163.com/hehaifeng1984@126/blog/static/690011362013101044011568/ 教程 https: ...