流(stream)是对串行传输的数据的一种抽象表示,底层的设备可以是文件、外部设备、主存、网络套接字等等。
流有三种基本的操作:写入、读取和查找。
如果数据从内存缓冲区传输到外部源,这样的流叫作“写入流”。
如果数据从外部源传输到内存缓冲区,这样的流叫作“读取流”。
在网络上传输数据时,试用的是网络流(NetworkStream)。网络流的意思是数据在网络的各个位置之间是以连续的形式传输的。为了处理这种流,C#在System.Net.Socket命名空间中提供了一个专门的NetworkStream类,用于通过网络套接字发送和接受数据。
NetworkStream类支持对网络数据的同步或异步访问,它可以被是为在数据来源端和接收端之间架设了一个数据通道,这样我们读取和写入数据就可以针对这个通道来进行。
对于NetworkStream流,写入操作是指从来源端内存缓冲区到网络上的数据传输;读取操作是从网络上到接受端内存缓冲区(如字节数组)的数据传输。如图所示。
图 NetworkStream流的数据传输
构造NetworkStream对象的常用形式为
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); NetWorkStream networkStream = new NetworkStream(socket);
一旦构造了一个NetworkStream对象,就不需要Socket对象了。也就是说,再关闭网络连接之前就一直试用NetworkStream对象发送和接受网络数据。表列出了NetworkStream类提供的常用属性。
表 NetworkStream类常用属性。
属性 | 说明 |
CanRead | 指示NetworkStream是否支持读操作,默认值为True |
CanWrite | 指示NetworkStream是否支持写操作,默认值为True |
CanSeek | 指示NetworkStream流是否支持查找,该属性总是返回False |
DataAvailable | 指示NetworkStream上是否有可用的数据,有则为真 |
Position | 获取或设置流中的当前位置,此属性始终引发NotSupportedException |
Readable | 指示NetworkStream流是否可读,为真时可读;假时不可读 |
Writeable | 指示NetworkStream流是否可写,为真时可写;假时不可写 |
在这个表中,比较常用的一个属性就是DataAvailable,通过这个属性,可以迅速查看在缓冲区中是否有数据等待读出。
注意:网络流没有当前位置的概念,因此不支持查找和对数据流的随机访问,相应属性CanSeek 始终返回false , 而读取Position 属性和调用Seek 方法时, 都将引发NotSupportedException 异常。
表 列出了NetworkStream 类的常用方法
表 NetworkStream类的常用方法
方法 | 说明 |
BeginRead方法 | 从NetworkStream流开始异步读取 |
BeginWrite方法 | 开始向NetworkStream流异步写入 |
EndRead方法 | 结束对一个NetworkStream流的异步读取 |
EndWrite方法 | 结束向一个NetworkStream流的异步写入 |
Read方法 | 从NetworkStream流中读取数据 |
Write方法 | 向NetworkStream流中写入数据 |
ReadByte方法 | 从NetworkStream流中读取一个字节的数据 |
WriteByte方法 | 向NetworkStream流中写入一个字节的数据 |
Flush方法 | 从NetworkStream流中取走所有数据 |
Close方法 | 关闭NetworkStream对象 |
Dispose方法 | 释放NetworkStream占用的资源 |
Seek方法 | 查找NetworkStream流的当前位置,此方法将引发NotSupportedException |
网络数据传输完成后,不要忘记用Close 方法关闭NetworkStream 对象。