介绍开源的.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 (existingConnections.Count > 0)
                {
                    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[0];
                }
                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(new IPEndPoint(ip, 0), 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>();
            foreach (IPEndPoint endPoint in Connection.ExistingLocalListenEndPoints(ConnectionType.TCP, new IPEndPoint(ipAddress, 0)))
                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
    }
时间: 2024-10-12 04:56:42

介绍开源的.net通信框架NetworkComms框架 源码分析(二十二 )TCPConnectionStatic的相关文章

缓存框架OSCache部分源码分析

在并发量比较大的场景,如果采用直接访问数据库的方式,将会对数据库带来巨大的压力,严重的情况下可能会导致数据库不可用状态,并且时间的消耗也是不能容忍的.在这种情况下,一般采用缓存的方式.将经常访问的热点数据提前加载到内存中,这样能够大大降低数据库的压力. OSCache是一个开源的缓存框架,虽然现在已经停止维护了,但是对于OSCache的实现还是值得学习和借鉴的.下面通过OSCache的部分源码分析OSCache的设计思想. 缓存数据结构 通常缓存都是通过<K,V>这种数据结构存储,但缓存都是应

android-----XUtils框架之HttpUtils源码分析

之前我们对Volley框架源码进行了分析,知道了他适用于频繁的网络请求,但是不太适合post较大数据以及文件的上传操作,在项目中为了弥补Volley的这个缺陷,使用了XUtils框架的HttpUtils实现了文件上传的操作,上一篇博客我们通过HttpUtils实现了照片上传的实例,见:android-----基于XUtils客户端以及服务器端实现,当然文件上传的方法类似于照片上传,有时间的话单独写一篇博客介绍,这篇博客我们从源码角度来分析HttpUtils的实现原理,希望对这几天的学习做个总结:

KopDB 框架学习2——源码分析

我的博客:http://mrfufufu.github.io/ 上次我们主要是对 KopDB 框架的使用进行了分析,它是非常简单有用的.这次主要是对它的源码进行分析,进一步的来了解它的真面目. 点击这里去往 "KopDB 框架学习1--使用" 因为 KopDB 采用的是对象关系映射(ORM)模式,即我们使用的编程语言是面向对象语言,而我们使用的数据库则是关系型数据库,那么将面向对象的语言和面向关系的数据库之间建立一种映射关系,这就是对象关系映射了. 使用 ORM 模式,主要是因为我们平

android-----XUtils框架之BitmapUtils源码分析

上一篇使用XUtils的BitmapUtils实现了一个照片墙的功能,参见:android-----XUtils框架之BitmapUtils加载照片实现,这一篇我们从源码的角度分析下BitmapUtils到底是怎么一个执行流程的: 先来回顾下之前我们使用BitmapUtils的步骤: 很简单,就只有两步: (1)通过BitmapUtils的构造函数创建对象: (2)调用BitmapUtils对象的display方法: 好了,我们先从创建BitmapUtils对象开始分析,很自然想到了Bitmap

首选项框架PreferenceFragment部分源码分析

因为要改一些settings里面的bug以及之前在里面有做过勿扰模式,准备对勿扰模式做一个总结,那先分析一下settings的源码,里面的核心应该就是android3.0 上面的首选项框架PreferenceFragment.因为在3.0之前都是把这些东西放在PreferenceActivity的,但是3.0之后google建议把setting放在PreferenceFragment,但是PreferenceActivity也同时在用的,下面就此总结一下: PreferenceActivity的

Java依赖注入库框架 Dagger的源码分析(一)

1.GeneratedAdapters 对应的注释上面是这么说的: A single point for API used in common by Adapters and Adapter generators 被Adapters以及Adapter的生产者广泛使用 通过代码,可以注意到,这是一个final类,是不允许被重载的. 他的构造函数是一个空的构造函数. 同时带有下面的常量的定义: private static final String SEPARATOR = "$$"; pu

Mahout协同过滤框架Taste的源码分析

推荐过程 主要分成了如下几步来完成推荐1. 输入数据预处理2. 获取评分矩阵3. 计算物品相似度4. 矩阵乘法5. 数据过滤6. 计算推荐 测试数据 user&item 1 2 3 4 5 1 3 3 3 2 0 2 4 4 4 0 0 3 5 5 5 0 3 4 4 4 4 1 4 继续阅读 →

Django框架——CBV及源码分析

CBV (基于类的视图函数) 代码示例: urls.py url(r'^login/',views.MyLogin.as_view()) views.py from django.views import View class MyLogin(View): def get(self,request): print("from MyLogin get方法") return render(request,'login.html') def post(self,request): retur

介绍开源的.net通信框架NetworkComms框架 源码分析

原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 售价249英镑 我曾经花了2千多购买过此通讯框架, 目前作者已经开源  许可是:Apache License v2 开源地址是:https://github.com/MarcFletcher/NetworkComms.Net 这个框架给我的感觉是,代码很优美,运行很稳定,我有一个项目使用此框架已经稳定运行1年多.这个框架能够

Android网络框架源码分析一---Volley

转载自 http://www.jianshu.com/p/9e17727f31a1?utm_campaign=maleskine&utm_content=note&utm_medium=mobile_author_hots&utm_source=recommendation 公司最近新起了一个项目,对喜欢尝鲜的我们来说,好处就是我们可以在真实的项目中想尝试一些新技术,验证想法.新项目对网络框架的选取,我们存在三种方案: 1.和我们之前的项目一样,使用Loader + HttpCli