原文网址: http://www.cnblogs.com/csdev

Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 目前作者已经开源  许可是:Apache License v2

开源地址是:https://github.com/MarcFletcher/NetworkComms.Net

线程安全的数据流

    /// <summary>
        /// A wrapper around a stream to ensure it can be accessed in a thread safe way. The .net implementation of Stream.Synchronized is not suitable on its own.
        /// 线程安全的数据流  .net实现的Stream.Synchronized 不适合其本身
        /// </summary>
        public class ThreadSafeStream : Stream, IDisposable
        {
            private Stream _innerStream;
            private object streamLocker = new object();

            /// <summary>
            /// If true the internal stream will be disposed once the data has been written to the network
            /// 如果设置为True  当数据写入到网络后 内部的数据流将会释放
            /// </summary>
            public bool DiposeInnerStreamOnDispose { get; set; }

            /// <summary>
            /// Create a thread safe stream. Once any actions are complete the stream must be correctly disposed by the user.
            /// 创建一个新的线程安全数据流   一旦操作完成数据流必须正确的释放
            /// </summary>
            /// <param name="stream">The stream to make thread safe</param>
            public ThreadSafeStream(Stream stream)
            {
                this.DiposeInnerStreamOnDispose = false;
                this._innerStream = stream;
            }

            /// <summary>
            /// Create a thread safe stream.
            /// 创建一个新的线程安全数据流
            /// </summary>
            /// <param name="stream">数据流  The stream to make thread safe.</param>
            /// <param name="closeStreamAfterSend">发送完成后内部数据流是否释放  If true the provided stream will be disposed once data has been written to the network. If false the stream must be disposed of correctly by the user</param>
            public ThreadSafeStream(Stream stream, bool closeStreamAfterSend)
            {
                this.DiposeInnerStreamOnDispose = closeStreamAfterSend;
                this._innerStream = stream;
            }

            /// <summary>
            /// The total length of the internal stream
            /// 内部数据流的长度
            /// </summary>
            public override long Length
            {
                get { lock (streamLocker) return _innerStream.Length; }
            }

            /// <inheritdoc />
            public override void SetLength(long value)
            {
                lock (streamLocker) _innerStream.SetLength(value);
            }

            /// <summary>
            /// The current position of the internal stream
            /// 内部数据流的当前位置
            /// </summary>
            public override long Position
            {
                get { lock (streamLocker) return _innerStream.Position; }
                set { lock (streamLocker) _innerStream.Position = value; }
            }

            /// <inheritdoc />
            public override long Seek(long offset, SeekOrigin origin)
            {
                lock (streamLocker) return _innerStream.Seek(offset, origin);
            }

            /// <summary>
            /// Returns data from entire Stream
            /// 从数据流中返回所有数据
            /// </summary>
            /// <param name="numberZeroBytesPrefex">是否存在0前缀 If non zero will append N 0 value bytes to the start of the returned array</param>
            /// <returns></returns>
            )
            {
                lock (streamLocker)
                {
                    _innerStream.Seek(, SeekOrigin.Begin);
                    byte[] returnData = new byte[_innerStream.Length + numberZeroBytesPrefex];
                    _innerStream.Read(returnData, numberZeroBytesPrefex, returnData.Length - numberZeroBytesPrefex);
                    return returnData;
                }
            }

            /// <summary>
            /// Returns data from the specified portion of Stream
            /// 从数据流的指定位置返回数据
            /// </summary>
            /// <param name="start">开始位置  The start position of the desired bytes</param>
            /// <param name="length">长度  The total number of desired bytes, not including the zero byte prefix and append parameters</param>
            /// <param name="numberZeroBytesPrefix">0前缀  If non zero will append N 0 value bytes to the start of the returned array</param>
            /// <param name="numberZeroBytesAppend">0后缀  If non zero will append N 0 value bytes to the end of the returned array</param>
            /// <returns></returns>
            , )
            {
                if (length > int.MaxValue)
                    throw new ArgumentOutOfRangeException("length", "Unable to return array whose size is larger than int.MaxValue. Consider requesting multiple smaller arrays.");

                lock (streamLocker)
                {
                    if (start + length > _innerStream.Length)
                        throw new ArgumentOutOfRangeException("length", "Provided start and length parameters reference past the end of the available stream.");

                    _innerStream.Seek(start, SeekOrigin.Begin);
                    byte[] returnData = new byte[length + numberZeroBytesPrefix + numberZeroBytesAppend];
                    _innerStream.Read(returnData, numberZeroBytesPrefix, (int)length);
                    return returnData;
                }
            }

            /// <summary>
            /// Return the MD5 hash of the current <see cref="ThreadSafeStream"/> as a string
            /// 返回当前“线程安全数据流”的MD5哈希值
            /// </summary>
            /// <returns></returns>
            public string MD5()
            {
                lock (streamLocker)
                    return StreamTools.MD5(_innerStream);
            }

            /// <summary>
            /// Return the MD5 hash of part of the current <see cref="ThreadSafeStream"/> as a string
            /// 返回当前“线程安全数据流”指定部分的MD5哈希值
            /// </summary>
            /// <param name="start">开始位置  The start position in the stream</param>
            /// <param name="length">长度 The length of stream to MD5</param>
            /// <returns></returns>
            public string MD5(long start, int length)
            {
                using (MemoryStream partialStream = new MemoryStream(length))
                {
                    lock (streamLocker)
                    {
                        StreamTools.Write(_innerStream, start, length, partialStream, , , );
                        return StreamTools.MD5(partialStream);
                    }
                }
            }

            /// <summary>
            /// Writes the provided buffer to the internal stream starting at the provided position within the internal stream
            /// 把 字节数组 从内部数据流指定的位置开始写入
            /// </summary>
            /// <param name="buffer"></param>
            /// <param name="startPosition"></param>
            public void Write(byte[] buffer, long startPosition)
            {
                if (buffer == null) throw new ArgumentNullException("data");

                lock (streamLocker)
                {
                    _innerStream.Seek(startPosition, SeekOrigin.Begin);
                    _innerStream.Write(buffer, , buffer.Length);
                    _innerStream.Flush();
                }
            }

            /// <inheritdoc />
            public override void Write(byte[] buffer, int offset, int count)
            {
                if (buffer == null) throw new ArgumentNullException("buffer");

                lock (streamLocker) _innerStream.Write(buffer, offset, count);
            }

            /// <summary>
            /// Copies data specified by start and length properties from internal stream to the provided stream.
            /// 根据参数 从指定的开始位置复制指定长度的内部数据流到目标数据流中
            /// </summary>
            /// <param name="destinationStream">目标数据流  The destination stream to write to</param>
            /// <param name="startPosition"></param>
            /// <param name="length"></param>
            /// <param name="writeBufferSize">写入的缓冲区大小  The buffer size to use for copying stream contents</param>
            /// <param name="minTimeoutMS">超时最小时间   The minimum time allowed for any sized copy</param>
            /// <param name="timeoutMSPerKBWrite">每KB数据发送的超时时间   The timouts in milliseconds per KB to write</param>
            /// <returns>每KB数据发送的平均时间  The average time in milliseconds per byte written</returns>
            , )
            {
                lock (streamLocker)
                    return StreamTools.Write(_innerStream, startPosition, length, destinationStream, writeBufferSize, timeoutMSPerKBWrite, minTimeoutMS);
            }

            /// <summary>
            /// Attempts to return the buffer associated with the internal stream. In certain circumstances this is more efficient
            /// than copying the stream contents into a new buffer using ToArray. If the internal stream is not a memory stream
            /// will throw InvalidCastException. If access to the buffer is not allowed will throw an UnauthorizedAccessException.
            /// 尝试返回内部流相关的缓冲区。
            /// 在某些情况下,这比使用ToArray复制内容到一个新的缓冲区中更高效
            /// 如果内部数据流不是内存流 将会抛出异常
            /// 如果缓冲区不可访问 ,也会抛出异常
            /// </summary>
            /// <returns></returns>
            public byte[] GetBuffer()
            {
#if NETFX_CORE
            throw new  NotImplementedException("This method has not been implemented for Win RT");
#else
                MemoryStream _innerMemoryStream = _innerStream as MemoryStream;
                if (_innerMemoryStream != null)
                    return _innerMemoryStream.GetBuffer();
                else
                    throw new InvalidCastException("Unable to return stream buffer as inner stream is not a MemoryStream.");
#endif
            }

            /// <inheritdoc />
            public override int Read(byte[] buffer, int offset, int count)
            {
                lock (streamLocker) return _innerStream.Read(buffer, offset, count);
            }

            /// <summary>
            /// Disposes the internal stream if <see cref="DiposeInnerStreamOnDispose"/> is true.
            /// Use Close() to close the inner stream regardless of <see cref="DiposeInnerStreamOnDispose"/>.
            /// 如果 DiposeInnerStreamOnDispose属性设置为TRUE,释放内部数据流
            /// </summary>
            public new void Dispose()
            {
                if (DiposeInnerStreamOnDispose)
                {
                    lock (streamLocker) _innerStream.Dispose();
                }
            }

            /// <summary>
            /// Disposes the internal stream. If <see cref="DiposeInnerStreamOnDispose"/> is false, forceDispose
            /// must be true to dispose of the internal stream.
            /// 如果 DiposeInnerStreamOnDispose属性设置为False ,强制释放设定为True,来释放内部数据流
            /// </summary>
            /// <param name="forceDispose">If true the internal stream will be disposed regardless of <see cref="DiposeInnerStreamOnDispose"/> value.</param>
            public new void Dispose(bool forceDispose)
            {
                if (DiposeInnerStreamOnDispose || forceDispose)
                {
                    lock (streamLocker) _innerStream.Dispose();
                }
            }

            /// <inheritdoc />
            public override bool CanRead
            {
                get { lock (streamLocker) return _innerStream.CanRead; }
            }

            /// <inheritdoc />
            public override bool CanSeek
            {
                get { lock (streamLocker) return _innerStream.CanSeek; }
            }

            /// <inheritdoc />
            public override bool CanWrite
            {
                get { lock (streamLocker) return _innerStream.CanWrite; }
            }

            /// <inheritdoc />
            public override void Flush()
            {
                lock (streamLocker) _innerStream.Flush();
            }
        }

介绍开源的.net通信框架NetworkComms框架 源码分析(十三)ThreadSafeStream的更多相关文章

  1. DotNetty网络通信框架学习之源码分析

    DotNetty网络通信框架学习之源码分析 有关DotNetty框架,网上的详细资料不是很多,有不多的几个博友做了简单的介绍,也没有做深入的探究,我也根据源码中提供的demo做一下记录,方便后期查阅. ...

  2. 深入理解分布式调度框架TBSchedule及源码分析

    简介 由于最近工作比较忙,前前后后花了两个月的时间把TBSchedule的源码翻了个底朝天.关于TBSchedule的使用,网上也有很多参考资料,这里不做过多的阐述.本文着重介绍TBSchedule的 ...

  3. 设计模式(十五)——命令模式(Spring框架的JdbcTemplate源码分析)

    1 智能生活项目需求 看一个具体的需求 1) 我们买了一套智能家电,有照明灯.风扇.冰箱.洗衣机,我们只要在手机上安装 app 就可以控制对这些家电工作. 2) 这些智能家电来自不同的厂家,我们不想针 ...

  4. 设计模式(二十一)——解释器模式(Spring 框架中SpelExpressionParser源码分析)

    1 四则运算问题 通过解释器模式来实现四则运算,如计算 a+b-c 的值,具体要求 1) 先输入表达式的形式,比如 a+b+c-d+e,  要求表达式的字母不能重复 2) 在分别输入 a ,b, c, ...

  5. $Django cbv源码分析 djangorestframework框架之APIView源码分析

    1 CBV的源码分析 #视图 class login (View): pass #路由 url(r'^books/$', views.login.as_view()) #阅读源码: #左侧工程栏--- ...

  6. ④NuPlayer播放框架之Renderer源码分析

    [时间:2016-11] [状态:Open] [关键词:android,nuplayer,开源播放器,播放框架,渲染器,render] 0 导读 之前我们分析了NuPlayer的实现代码,本文将重点聚 ...

  7. ⑤NuPlayer播放框架之GenericSource源码分析

    [时间:2017-01] [状态:Open] [关键词:android,nuplayer,开源播放器,播放框架,GenericSource] 0 导读 GenericSource是NuPlayer:: ...

  8. ③NuPlayer播放框架之类NuPlayer源码分析

    [时间:2016-10] [状态:Open] [关键词:android,nuplayer,开源播放器,播放框架] 0 引言 差不多一个月了,继续分析AOSP的播放框架的源码.这次我们需要深入分析的是N ...

  9. Laravel开发:Laravel框架门面Facade源码分析

    前言 这篇文章我们开始讲 laravel 框架中的门面 Facade,什么是门面呢?官方文档: Facades(读音:/fəˈsäd/ )为应用程序的服务容器中可用的类提供了一个「静态」接口.Lara ...

  10. Android 应用框架层 SQLite 源码分析

    概述   Android 在应用框架层为开发者提供了 SQLite 相关操作接口,其归属于android.database.sqlite包底下,主要包含SQLiteProgram, SQLiteDat ...

随机推荐

  1. CDH版本升级

    近期项目中需要用oozie workflow调度hivesql,发现无法执行查询语句,见:https://community.cloudera.com/t5/Batch-Processing-and- ...

  2. OpenGL概述

    简介 状态机 glBegin()与glEnd() glFlush()与glFinish() OpenGL简介 OpenGL是图形硬件的一种软件接口.它被设计为硬件独立的接口,可用于多种不同硬件平台.O ...

  3. 伪类after的使用

    .center-tc { text-align: center; position: relative; color:red; &:before{ content:''; width: 10p ...

  4. mysql系统库INFORMATION_SCHEMA,MySQL,TEST,mysql系统表的作用

    本文简要说明了MySQL数据库安装好后自带的INFORMATION_SCHEMA,MySQL,TEST三个数据库的用途. 第一个数据库INFORMATION_SCHEMA: 提供了访问数据库元数据的方 ...

  5. linux项目-之监控-nagios

    nagios core plugins 对象 主机(交换机,路由器,防火墙,服务器,虚拟机等),主机组 服务(主机上提供的服务如80,3306,1521,21等)/资源(cpu,内存使用情况,磁盘,网 ...

  6. WCF:没有终结点在侦听可以接受消息的*这通常是由于不正确的地址或者 SOAP操作导致的。

    没有终结点在侦听可以接受消息的 http://xx.com/WebService.svc. 这通常是由于不正确的地址或者 SOAP 操作导致的.如果存在此情况,请参见 InnerException 以 ...

  7. python学习-day14:集合,函数,格式化

    一.集合 定义:由不同元素组成的集合.集合是一组无序排列的可hash值, 可以作为字典的key.元素必须是不可变类型:只能存放数字,字符串,字典 特性:集合的目的是将不同的值放在一起,不同的集合之间可 ...

  8. 【MySQL】结构行长度的一些限制

    今天被开发提交的DDL变更再次困惑,表中字段较多,希望将已有的两个varchar(4000)字段改为varchar(20000),我想innodb对varchar的存储不就是取前768字节记录当前行空 ...

  9. 如何测试手机上的SOAP客户端

    周四晚上,服务端和客户端的两个同事因为soap接口的问题争论了起来.服务端的同事认为客户端的同事发给服务端的soap消息的xml结构有问题,少了几个xml节点,导致服务器端解析出错.而客户端的同事认为 ...

  10. A*算法入门

    来源:http://www.cppblog.com/mythit/archive/2009/04/19/80492.aspx 在看下面这篇文章之前,先介绍几个理论知识,有助于理解A*算法. 启发式搜索 ...