BufferedStream Класс

Определение

Добавляет уровень буферизации в операциях чтения и записи в другие потоки. Этот класс не наследуется.

public ref class BufferedStream sealed : System::IO::Stream
public sealed class BufferedStream : System.IO.Stream
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class BufferedStream : System.IO.Stream
type BufferedStream = class
    inherit Stream
[<System.Runtime.InteropServices.ComVisible(true)>]
type BufferedStream = class
    inherit Stream
Public NotInheritable Class BufferedStream
Inherits Stream
Наследование
BufferedStream
Наследование
Атрибуты

Примеры

В следующих примерах кода показано, как использовать BufferedStream класс над классом NetworkStream для повышения производительности определенных операций ввода-вывода. Запустите сервер на удаленном компьютере перед запуском клиента. При запуске клиента укажите имя удаленного компьютера в качестве аргумента командной строки. dataArraySize Изменяйте значения и streamBufferSize константы для просмотра их влияния на производительность.

В первом примере показан код, который выполняется на клиенте, а во втором примере показан код, который выполняется на сервере.

Пример 1. Код, который выполняется на клиенте

#using <system.dll>

using namespace System;
using namespace System::IO;
using namespace System::Globalization;
using namespace System::Net;
using namespace System::Net::Sockets;
static const int streamBufferSize = 1000;
public ref class Client
{
private:
   literal int dataArraySize = 100;
   literal int numberOfLoops = 10000;
   Client(){}


public:
   static void ReceiveData( Stream^ netStream, Stream^ bufStream )
   {
      DateTime startTime;
      Double networkTime;
      Double bufferedTime = 0;
      int bytesReceived = 0;
      array<Byte>^receivedData = gcnew array<Byte>(dataArraySize);
      
      // Receive data using the NetworkStream.
      Console::WriteLine( "Receiving data using NetworkStream." );
      startTime = DateTime::Now;
      while ( bytesReceived < numberOfLoops * receivedData->Length )
      {
         bytesReceived += netStream->Read( receivedData, 0, receivedData->Length );
      }

      networkTime = (DateTime::Now - startTime).TotalSeconds;
      Console::WriteLine( "{0} bytes received in {1} seconds.\n", bytesReceived.ToString(), networkTime.ToString(  "F1" ) );
      
      // Receive data using the BufferedStream.
      Console::WriteLine(  "Receiving data using BufferedStream." );
      bytesReceived = 0;
      startTime = DateTime::Now;
      while ( bytesReceived < numberOfLoops * receivedData->Length )
      {
         bytesReceived += bufStream->Read( receivedData, 0, receivedData->Length );
      }

      bufferedTime = (DateTime::Now - startTime).TotalSeconds;
      Console::WriteLine( "{0} bytes received in {1} seconds.\n", bytesReceived.ToString(), bufferedTime.ToString(  "F1" ) );
      
      // Print the ratio of read times.
      Console::WriteLine( "Receiving data using the buffered "
      "network stream was {0} {1} than using the network "
      "stream alone.", (networkTime / bufferedTime).ToString(  "P0" ), bufferedTime < networkTime ? (String^)"faster" : "slower" );
   }

   static void SendData( Stream^ netStream, Stream^ bufStream )
   {
      DateTime startTime;
      Double networkTime;
      Double bufferedTime;
      
      // Create random data to send to the server.
      array<Byte>^dataToSend = gcnew array<Byte>(dataArraySize);
      (gcnew Random)->NextBytes( dataToSend );
      
      // Send the data using the NetworkStream.
      Console::WriteLine( "Sending data using NetworkStream." );
      startTime = DateTime::Now;
      for ( int i = 0; i < numberOfLoops; i++ )
      {
         netStream->Write( dataToSend, 0, dataToSend->Length );

      }
      networkTime = (DateTime::Now - startTime).TotalSeconds;
      Console::WriteLine( "{0} bytes sent in {1} seconds.\n", (numberOfLoops * dataToSend->Length).ToString(), networkTime.ToString(  "F1" ) );
      
      // Send the data using the BufferedStream.
      Console::WriteLine( "Sending data using BufferedStream." );
      startTime = DateTime::Now;
      for ( int i = 0; i < numberOfLoops; i++ )
      {
         bufStream->Write( dataToSend, 0, dataToSend->Length );

      }
      bufStream->Flush();
      bufferedTime = (DateTime::Now - startTime).TotalSeconds;
      Console::WriteLine( "{0} bytes sent in {1} seconds.\n", (numberOfLoops * dataToSend->Length).ToString(), bufferedTime.ToString(  "F1" ) );
      
      // Print the ratio of write times.
      Console::WriteLine( "Sending data using the buffered "
      "network stream was {0} {1} than using the network "
      "stream alone.\n", (networkTime / bufferedTime).ToString(  "P0" ), bufferedTime < networkTime ? (String^)"faster" : "slower" );
   }

};

int main( int argc, char *argv[] )
{
   
   // Check that an argument was specified when the 
   // program was invoked.
   if ( argc == 1 )
   {
      Console::WriteLine( "Error: The name of the host computer"
      " must be specified when the program is invoked." );
      return  -1;
   }

   String^ remoteName = gcnew String( argv[ 1 ] );
   
   // Create the underlying socket and connect to the server.
   Socket^ clientSocket = gcnew Socket( AddressFamily::InterNetwork,SocketType::Stream,ProtocolType::Tcp );
   clientSocket->Connect( gcnew IPEndPoint( Dns::Resolve( remoteName )->AddressList[ 0 ],1800 ) );
   Console::WriteLine(  "Client is connected.\n" );
   
   // Create a NetworkStream that owns clientSocket and 
   // then create a BufferedStream on top of the NetworkStream.
   NetworkStream^ netStream = gcnew NetworkStream( clientSocket,true );
   BufferedStream^ bufStream = gcnew BufferedStream( netStream,streamBufferSize );
   
   try
   {
      
      // Check whether the underlying stream supports seeking.
      Console::WriteLine( "NetworkStream {0} seeking.\n", bufStream->CanSeek ? (String^)"supports" : "does not support" );
      
      // Send and receive data.
      if ( bufStream->CanWrite )
      {
         Client::SendData( netStream, bufStream );
      }
      
      if ( bufStream->CanRead )
      {
         Client::ReceiveData( netStream, bufStream );
      }
      
   }
   finally
   {
      
      // When bufStream is closed, netStream is in turn closed,
      // which in turn shuts down the connection and closes
      // clientSocket.
      Console::WriteLine( "\nShutting down connection." );
      bufStream->Close();
      
   }

}
using System;
using System.IO;
using System.Globalization;
using System.Net;
using System.Net.Sockets;

public class Client
{
    const int dataArraySize    =   100;
    const int streamBufferSize =  1000;
    const int numberOfLoops    = 10000;

    static void Main(string[] args)
    {
        // Check that an argument was specified when the
        // program was invoked.
        if(args.Length == 0)
        {
            Console.WriteLine("Error: The name of the host computer" +
                " must be specified when the program is invoked.");
            return;
        }

        string remoteName = args[0];

        // Create the underlying socket and connect to the server.
        Socket clientSocket = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp);

        clientSocket.Connect(new IPEndPoint(
            Dns.Resolve(remoteName).AddressList[0], 1800));

        Console.WriteLine("Client is connected.\n");

        // Create a NetworkStream that owns clientSocket and
        // then create a BufferedStream on top of the NetworkStream.
        // Both streams are disposed when execution exits the
        // using statement.
        using(Stream
            netStream = new NetworkStream(clientSocket, true),
            bufStream =
                  new BufferedStream(netStream, streamBufferSize))
        {
            // Check whether the underlying stream supports seeking.
            Console.WriteLine("NetworkStream {0} seeking.\n",
                bufStream.CanSeek ? "supports" : "does not support");

            // Send and receive data.
            if(bufStream.CanWrite)
            {
                SendData(netStream, bufStream);
            }
            if(bufStream.CanRead)
            {
                ReceiveData(netStream, bufStream);
            }

            // When bufStream is closed, netStream is in turn
            // closed, which in turn shuts down the connection
            // and closes clientSocket.
            Console.WriteLine("\nShutting down the connection.");
            bufStream.Close();
        }
    }

    static void SendData(Stream netStream, Stream bufStream)
    {
        DateTime startTime;
        double networkTime, bufferedTime;

        // Create random data to send to the server.
        byte[] dataToSend = new byte[dataArraySize];
        new Random().NextBytes(dataToSend);

        // Send the data using the NetworkStream.
        Console.WriteLine("Sending data using NetworkStream.");
        startTime = DateTime.Now;
        for(int i = 0; i < numberOfLoops; i++)
        {
            netStream.Write(dataToSend, 0, dataToSend.Length);
        }
        networkTime = (DateTime.Now - startTime).TotalSeconds;
        Console.WriteLine("{0} bytes sent in {1} seconds.\n",
            numberOfLoops * dataToSend.Length,
            networkTime.ToString("F1"));

        // Send the data using the BufferedStream.
        Console.WriteLine("Sending data using BufferedStream.");
        startTime = DateTime.Now;
        for(int i = 0; i < numberOfLoops; i++)
        {
            bufStream.Write(dataToSend, 0, dataToSend.Length);
        }
        bufStream.Flush();
        bufferedTime = (DateTime.Now - startTime).TotalSeconds;
        Console.WriteLine("{0} bytes sent in {1} seconds.\n",
            numberOfLoops * dataToSend.Length,
            bufferedTime.ToString("F1"));

        // Print the ratio of write times.
        Console.WriteLine("Sending data using the buffered " +
            "network stream was {0} {1} than using the network " +
            "stream alone.\n",
            (networkTime/bufferedTime).ToString("P0"),
            bufferedTime < networkTime ? "faster" : "slower");
    }

    static void ReceiveData(Stream netStream, Stream bufStream)
    {
        DateTime startTime;
        double networkTime, bufferedTime = 0;
        int bytesReceived = 0;
        byte[] receivedData = new byte[dataArraySize];

        // Receive data using the NetworkStream.
        Console.WriteLine("Receiving data using NetworkStream.");
        startTime = DateTime.Now;
        while(bytesReceived < numberOfLoops * receivedData.Length)
        {
            bytesReceived += netStream.Read(
                receivedData, 0, receivedData.Length);
        }
        networkTime = (DateTime.Now - startTime).TotalSeconds;
        Console.WriteLine("{0} bytes received in {1} seconds.\n",
            bytesReceived.ToString(),
            networkTime.ToString("F1"));

        // Receive data using the BufferedStream.
        Console.WriteLine("Receiving data using BufferedStream.");
        bytesReceived = 0;
        startTime = DateTime.Now;

        int numBytesToRead = receivedData.Length;

        while (numBytesToRead > 0)
        {
            // Read may return anything from 0 to numBytesToRead.
            int n = bufStream.Read(receivedData,0, receivedData.Length);
            // The end of the file is reached.
            if (n == 0)
                break;
            bytesReceived += n;
            numBytesToRead -= n;
        }

        bufferedTime = (DateTime.Now - startTime).TotalSeconds;
        Console.WriteLine("{0} bytes received in {1} seconds.\n",
            bytesReceived.ToString(),
            bufferedTime.ToString("F1"));

        // Print the ratio of read times.
        Console.WriteLine("Receiving data using the buffered network" +
            " stream was {0} {1} than using the network stream alone.",
            (networkTime/bufferedTime).ToString("P0"),
            bufferedTime < networkTime ? "faster" : "slower");
    }
}
module Client

open System
open System.IO
open System.Net
open System.Net.Sockets

let dataArraySize    =   100
let streamBufferSize =  1000
let numberOfLoops    = 10000

let sendData (netStream: Stream) (bufStream: Stream) =
    // Create random data to send to the server.
    let dataToSend = Array.zeroCreate dataArraySize
    Random().NextBytes dataToSend

    // Send the data using the NetworkStream.
    printfn "Sending data using NetworkStream."
    let startTime = DateTime.Now
    for _ = 0 to numberOfLoops - 1 do
        netStream.Write(dataToSend, 0, dataToSend.Length)
    let networkTime = (DateTime.Now - startTime).TotalSeconds
    printfn $"{numberOfLoops * dataToSend.Length} bytes sent in {networkTime:F1} seconds.\n"

    // Send the data using the BufferedStream.
    printfn "Sending data using BufferedStream."
    let startTime = DateTime.Now
    for _ = 0 to numberOfLoops - 1 do
        bufStream.Write(dataToSend, 0, dataToSend.Length)
    bufStream.Flush()
    let bufferedTime = (DateTime.Now - startTime).TotalSeconds
    printfn $"{numberOfLoops * dataToSend.Length} bytes sent in {bufferedTime:F1} seconds.\n"

    // Print the ratio of write times.
    printfn $"""Sending data using the buffered network stream was {networkTime / bufferedTime:P0} {if bufferedTime < networkTime then "faster" else "slower"} than using the network stream alone."""
    printfn ""

let receiveData (netStream: Stream) (bufStream: Stream) =
    let mutable bytesReceived = 0
    let receivedData = Array.zeroCreate dataArraySize

    // Receive data using the NetworkStream.
    printfn "Receiving data using NetworkStream."
    let startTime = DateTime.Now
    while bytesReceived < numberOfLoops * receivedData.Length do
        bytesReceived <- bytesReceived + netStream.Read(receivedData, 0, receivedData.Length)
    let networkTime = (DateTime.Now - startTime).TotalSeconds
    printfn $"{bytesReceived} bytes received in {networkTime:F1} seconds.\n"

    // Receive data using the BufferedStream.
    printfn "Receiving data using BufferedStream."
    bytesReceived <- 0
    let startTime = DateTime.Now

    let mutable numBytesToRead = receivedData.Length

    let mutable broken = false
    while not broken && numBytesToRead > 0 do
        // Read may return anything from 0 to numBytesToRead.
        let n = bufStream.Read(receivedData,0, receivedData.Length)
        // The end of the file is reached.
        if n = 0 then
            broken <- true
        else
            bytesReceived <- bytesReceived + n
            numBytesToRead <- numBytesToRead - n

    let bufferedTime = (DateTime.Now - startTime).TotalSeconds
    printfn $"{bytesReceived} bytes received in {bufferedTime:F1} seconds.\n"

    // Print the ratio of read times.
    printfn $"""Receiving data using the buffered network stream was {networkTime / bufferedTime:P0} {if bufferedTime < networkTime then "faster" else "slower"} than using the network stream alone."""

[<EntryPoint>]
let main args =
    // Check that an argument was specified when the
    // program was invoked.
    if args.Length = 0 then
        printfn "Error: The name of the host computer must be specified when the program is invoked."
    else
        let remoteName = args[0]

        // Create the underlying socket and connect to the server.
        let clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)

        clientSocket.Connect(IPEndPoint(Dns.GetHostEntry(remoteName).AddressList[0], 1800))

        printfn "Client is connected.\n"

        // Create a NetworkStream that owns clientSocket and
        // then create a BufferedStream on top of the NetworkStream.
        // Both streams are disposed when execution exits the
        // using statement.
        use netStream = new NetworkStream(clientSocket, true)
        use bufStream = new BufferedStream(netStream, streamBufferSize)
        // Check whether the underlying stream supports seeking.
        printfn $"""NetworkStream {if bufStream.CanSeek then "supports" else "does not support"} seeking.\n"""

        // Send and receive data.
        if bufStream.CanWrite then
            sendData netStream bufStream
        if bufStream.CanRead then
            receiveData netStream bufStream

        // When bufStream is closed, netStream is in turn
        // closed, which in turn shuts down the connection
        // and closes clientSocket.
        printfn "\nShutting down the connection."
        bufStream.Close()
    0
' Compile using /r:System.dll.
Imports System.IO
Imports System.Globalization
Imports System.Net
Imports System.Net.Sockets

Public Class Client 

    Const dataArraySize As Integer    =   100
    Const streamBufferSize As Integer =  1000
    Const numberOfLoops As Integer    = 10000

    Shared Sub Main(args As String()) 
    
        ' Check that an argument was specified when the 
        ' program was invoked.
        If args.Length = 0 Then
            Console.WriteLine("Error: The name of the host " & _
                "computer must be specified when the program " & _ 
                "is invoked.")
            Return
        End If

        Dim remoteName As String = args(0)

        ' Create the underlying socket and connect to the server.
        Dim clientSocket As New Socket(AddressFamily.InterNetwork, _
            SocketType.Stream, ProtocolType.Tcp)

        clientSocket.Connect(New IPEndPoint( _
            Dns.Resolve(remoteName).AddressList(0), 1800))

        Console.WriteLine("Client is connected." & vbCrLf)

        ' Create a NetworkStream that owns clientSocket and then 
        ' create a BufferedStream on top of the NetworkStream.
        Dim netStream As New NetworkStream(clientSocket, True)
        Dim bufStream As New _
            BufferedStream(netStream, streamBufferSize)
        
        Try
            ' Check whether the underlying stream supports seeking.
            If bufStream.CanSeek Then
                Console.WriteLine("NetworkStream supports" & _
                    "seeking." & vbCrLf)
            Else
                Console.WriteLine("NetworkStream does not " & _
                    "support seeking." & vbCrLf)
            End If

            ' Send and receive data.
            If bufStream.CanWrite Then
                SendData(netStream, bufStream)
            End If            
            If bufStream.CanRead Then
                ReceiveData(netStream, bufStream)
            End If
        Finally

            ' When bufStream is closed, netStream is in turn 
            ' closed, which in turn shuts down the connection 
            ' and closes clientSocket.
            Console.WriteLine(vbCrLf & "Shutting down the connection.")
            bufStream.Close()
        End Try
    End Sub

    Shared Sub SendData(netStream As Stream, bufStream As Stream)
    
        Dim startTime As DateTime 
        Dim networkTime As Double, bufferedTime As Double 

        ' Create random data to send to the server.
        Dim dataToSend(dataArraySize - 1) As Byte
        Dim randomGenerator As New Random()
        randomGenerator.NextBytes(dataToSend)

        ' Send the data using the NetworkStream.
        Console.WriteLine("Sending data using NetworkStream.")
        startTime = DateTime.Now
        For i As Integer = 1 To numberOfLoops
            netStream.Write(dataToSend, 0, dataToSend.Length)
        Next i
        networkTime = DateTime.Now.Subtract(startTime).TotalSeconds
        Console.WriteLine("{0} bytes sent in {1} seconds." & vbCrLf, _
            numberOfLoops * dataToSend.Length, _
            networkTime.ToString("F1"))

        ' Send the data using the BufferedStream.
        Console.WriteLine("Sending data using BufferedStream.")
        startTime = DateTime.Now
        For i As Integer = 1 To numberOfLoops
            bufStream.Write(dataToSend, 0, dataToSend.Length)
        Next i
        
        bufStream.Flush()
        bufferedTime = DateTime.Now.Subtract(startTime).TotalSeconds
        Console.WriteLine("{0} bytes sent In {1} seconds." & vbCrLf, _
            numberOfLoops * dataToSend.Length, _
            bufferedTime.ToString("F1"))

        ' Print the ratio of write times.
        Console.Write("Sending data using the buffered " & _
            "network stream was {0}", _
            (networkTime/bufferedTime).ToString("P0"))
        If bufferedTime < networkTime Then
            Console.Write(" faster")
        Else
            Console.Write(" slower")
        End If
        Console.WriteLine(" than using the network stream alone.")
    End Sub

    Shared Sub ReceiveData(netStream As Stream, bufStream As Stream)
    
        Dim startTime As DateTime 
        Dim networkTime As Double, bufferedTime As Double = 0

        Dim bytesReceived As Integer = 0
        Dim receivedData(dataArraySize - 1) As Byte

        ' Receive data using the NetworkStream.
        Console.WriteLine("Receiving data using NetworkStream.")
        startTime = DateTime.Now
        While bytesReceived < numberOfLoops * receivedData.Length
            bytesReceived += netStream.Read( _
                receivedData, 0, receivedData.Length)
        End While
        networkTime = DateTime.Now.Subtract(startTime).TotalSeconds
        Console.WriteLine("{0} bytes received in {1} " & _
            "seconds." & vbCrLf, _
            bytesReceived.ToString(), _
            networkTime.ToString("F1"))

        ' Receive data using the BufferedStream.
        Console.WriteLine("Receiving data using BufferedStream.")
        bytesReceived = 0
        startTime = DateTime.Now

        Dim numBytesToRead As Integer = receivedData.Length
        Dim n As Integer
        Do While numBytesToRead > 0

            'Read my return anything from 0 to numBytesToRead
            n = bufStream.Read(receivedData, 0, receivedData.Length)
            'The end of the file is reached.
            If n = 0 Then
                Exit Do
            End If

            bytesReceived += n
            numBytesToRead -= n
        Loop

        bufferedTime = DateTime.Now.Subtract(startTime).TotalSeconds
        Console.WriteLine("{0} bytes received in {1} " & _
            "seconds." & vbCrLf, _
            bytesReceived.ToString(), _
            bufferedTime.ToString("F1"))

        ' Print the ratio of read times.
        Console.Write("Receiving data using the buffered " & _
            "network stream was {0}", _
            (networkTime/bufferedTime).ToString("P0"))
        If bufferedTime < networkTime Then
            Console.Write(" faster")
        Else
            Console.Write(" slower")
        End If
        Console.WriteLine(" than using the network stream alone.")
    End Sub
End Class

Пример 2. Код, который выполняется на сервере

#using <system.dll>

using namespace System;
using namespace System::Net;
using namespace System::Net::Sockets;
int main()
{
   
   // This is a Windows Sockets 2 error code.
   const int WSAETIMEDOUT = 10060;
   Socket^ serverSocket;
   int bytesReceived;
   int totalReceived = 0;
   array<Byte>^receivedData = gcnew array<Byte>(2000000);
   
   // Create random data to send to the client.
   array<Byte>^dataToSend = gcnew array<Byte>(2000000);
   (gcnew Random)->NextBytes( dataToSend );
   IPAddress^ ipAddress = Dns::Resolve( Dns::GetHostName() )->AddressList[ 0 ];
   IPEndPoint^ ipEndpoint = gcnew IPEndPoint( ipAddress,1800 );
   
   // Create a socket and listen for incoming connections.
   Socket^ listenSocket = gcnew Socket( AddressFamily::InterNetwork,SocketType::Stream,ProtocolType::Tcp );
   try
   {
      listenSocket->Bind( ipEndpoint );
      listenSocket->Listen( 1 );
      
      // Accept a connection and create a socket to handle it.
      serverSocket = listenSocket->Accept();
      Console::WriteLine( "Server is connected.\n" );
   }
   finally
   {
      listenSocket->Close();
   }

   try
   {
      
      // Send data to the client.
      Console::Write( "Sending data ... " );
      int bytesSent = serverSocket->Send( dataToSend, 0, dataToSend->Length, SocketFlags::None );
      Console::WriteLine( "{0} bytes sent.\n", bytesSent.ToString() );
      
      // Set the timeout for receiving data to 2 seconds.
      serverSocket->SetSocketOption( SocketOptionLevel::Socket, SocketOptionName::ReceiveTimeout, 2000 );
      
      // Receive data from the client.
      Console::Write( "Receiving data ... " );
      try
      {
         do
         {
            bytesReceived = serverSocket->Receive( receivedData, 0, receivedData->Length, SocketFlags::None );
            totalReceived += bytesReceived;
         }
         while ( bytesReceived != 0 );
      }
      catch ( SocketException^ e ) 
      {
         if ( e->ErrorCode == WSAETIMEDOUT )
         {
            
            // Data was not received within the given time.
            // Assume that the transmission has ended.
         }
         else
         {
            Console::WriteLine( "{0}: {1}\n", e->GetType()->Name, e->Message );
         }
      }
      finally
      {
         Console::WriteLine( "{0} bytes received.\n", totalReceived.ToString() );
      }

   }
   finally
   {
      serverSocket->Shutdown( SocketShutdown::Both );
      Console::WriteLine( "Connection shut down." );
      serverSocket->Close();
   }

}
using System;
using System.Net;
using System.Net.Sockets;

public class Server
{
    static void Main()
    {
        // This is a Windows Sockets 2 error code.
        const int WSAETIMEDOUT = 10060;

        Socket serverSocket;
        int bytesReceived, totalReceived = 0;
        byte[] receivedData = new byte[2000000];

        // Create random data to send to the client.
        byte[] dataToSend = new byte[2000000];
        new Random().NextBytes(dataToSend);

        IPAddress ipAddress =
            Dns.Resolve(Dns.GetHostName()).AddressList[0];

        IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, 1800);

        // Create a socket and listen for incoming connections.
        using(Socket listenSocket = new Socket(
            AddressFamily.InterNetwork, SocketType.Stream,
            ProtocolType.Tcp))
        {
            listenSocket.Bind(ipEndpoint);
            listenSocket.Listen(1);

            // Accept a connection and create a socket to handle it.
            serverSocket = listenSocket.Accept();
            Console.WriteLine("Server is connected.\n");
        }

        try
        {
            // Send data to the client.
            Console.Write("Sending data ... ");
            int bytesSent = serverSocket.Send(
                dataToSend, 0, dataToSend.Length, SocketFlags.None);
            Console.WriteLine("{0} bytes sent.\n",
                bytesSent.ToString());

            // Set the timeout for receiving data to 2 seconds.
            serverSocket.SetSocketOption(SocketOptionLevel.Socket,
                SocketOptionName.ReceiveTimeout, 2000);

            // Receive data from the client.
            Console.Write("Receiving data ... ");
            try
            {
                do
                {
                    bytesReceived = serverSocket.Receive(receivedData,
                        0, receivedData.Length, SocketFlags.None);
                    totalReceived += bytesReceived;
                }
                while(bytesReceived != 0);
            }
            catch(SocketException e)
            {
                if(e.ErrorCode == WSAETIMEDOUT)
                {
                    // Data was not received within the given time.
                    // Assume that the transmission has ended.
                }
                else
                {
                    Console.WriteLine("{0}: {1}\n",
                        e.GetType().Name, e.Message);
                }
            }
            finally
            {
                Console.WriteLine("{0} bytes received.\n",
                    totalReceived.ToString());
            }
        }
        finally
        {
            serverSocket.Shutdown(SocketShutdown.Both);
            Console.WriteLine("Connection shut down.");
            serverSocket.Close();
        }
    }
}
module Server

open System
open System.Net
open System.Net.Sockets

// This is a Windows Sockets 2 error code.
let WSAETIMEDOUT = 10060

let mutable bytesReceived = -1 
let mutable totalReceived = 0
let receivedData = Array.zeroCreate 2000000

// Create random data to send to the client.
let dataToSend = Array.zeroCreate 2000000
Random().NextBytes dataToSend

let ipAddress = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0]

let ipEndpoint = IPEndPoint(ipAddress, 1800)

// Create a socket and listen for incoming connections.
let serverSocket = 
    use listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
    listenSocket.Bind ipEndpoint
    listenSocket.Listen 1

    // Accept a connection and create a socket to handle it.
    listenSocket.Accept()

printfn "Server is connected.\n"

try
    // Send data to the client.
    printf "Sending data ... "
    let bytesSent = serverSocket.Send(dataToSend, 0, dataToSend.Length, SocketFlags.None)
    printfn $"{bytesSent} bytes sent.\n"

    // Set the timeout for receiving data to 2 seconds.
    serverSocket.SetSocketOption(SocketOptionLevel.Socket,
        SocketOptionName.ReceiveTimeout, 2000)

    // Receive data from the client.
    printf "Receiving data ... "
    try
        try
            while bytesReceived <> 0 do
                bytesReceived <- serverSocket.Receive(receivedData, 0, receivedData.Length, SocketFlags.None)
                totalReceived <- totalReceived + bytesReceived

        with :? SocketException as e ->
            if e.ErrorCode = WSAETIMEDOUT then
                // Data was not received within the given time.
                // Assume that the transmission has ended.
                ()
            else
                printfn $"{e.GetType().Name}: {e.Message}\n"
    finally
        printfn $"{totalReceived} bytes received.\n"
finally
    serverSocket.Shutdown SocketShutdown.Both
    printfn "Connection shut down."
    serverSocket.Close()
' Compile using /r:System.dll.
Imports System.Net
Imports System.Net.Sockets

Public Class Server 

    Shared Sub Main() 
    
        ' This is a Windows Sockets 2 error code.
        Const WSAETIMEDOUT As Integer = 10060

        Dim serverSocket As Socket 
        Dim bytesReceived As Integer
        Dim totalReceived As Integer = 0
        Dim receivedData(2000000-1) As Byte

        ' Create random data to send to the client.
        Dim dataToSend(2000000-1) As Byte
        Dim randomGenerator As New Random()
        randomGenerator.NextBytes(dataToSend)

        Dim ipAddress As IPAddress = _
            Dns.Resolve(Dns.GetHostName()).AddressList(0)

        Dim ipEndpoint As New IPEndPoint(ipAddress, 1800)

        ' Create a socket and listen for incoming connections.
        Dim listenSocket As New Socket(AddressFamily.InterNetwork, _
            SocketType.Stream, ProtocolType.Tcp)
        
        Try
            listenSocket.Bind(ipEndpoint)
            listenSocket.Listen(1)

            ' Accept a connection and create a socket to handle it.
            serverSocket = listenSocket.Accept()
            Console.WriteLine("Server is connected." & vbCrLf)
        Finally
            listenSocket.Close()
        End Try

        Try
            ' Send data to the client.
            Console.Write("Sending data ... ")
            Dim bytesSent As Integer = serverSocket.Send( _
                dataToSend, 0, dataToSend.Length, SocketFlags.None)
            Console.WriteLine("{0} bytes sent." & vbCrLf, _
                bytesSent.ToString())

            ' Set the timeout for receiving data to 2 seconds.
            serverSocket.SetSocketOption(SocketOptionLevel.Socket, _
                SocketOptionName.ReceiveTimeout, 2000)

            ' Receive data from the client.
            Console.Write("Receiving data ... ")
            Try
                Do
                    bytesReceived = serverSocket.Receive( _
                        receivedData, 0, receivedData.Length, _
                        SocketFlags.None)
                    totalReceived += bytesReceived
                Loop While bytesReceived <> 0
            Catch e As SocketException
                If(e.ErrorCode = WSAETIMEDOUT)
                
                    ' Data was not received within the given time.
                    ' Assume that the transmission has ended.
                Else
                    Console.WriteLine("{0}: {1}" & vbCrLf, _
                        e.GetType().Name, e.Message)
                End If
            Finally
                Console.WriteLine("{0} bytes received." & vbCrLf, _
                    totalReceived.ToString())
            End Try
        Finally
            serverSocket.Shutdown(SocketShutdown.Both)
            Console.WriteLine("Connection shut down.")
            serverSocket.Close()
        End Try
    
    End Sub
End Class

Комментарии

Буфер — это блок байтов в памяти, используемый для кэширования данных, тем самым уменьшая количество вызовов операционной системы. Буферы повышают производительность чтения и записи. Буфер можно использовать для чтения или записи, но никогда не одновременно. Методы Read автоматического BufferedStream Write обслуживания буфера.

Важно!

Этот тип реализует интерфейс IDisposable. По окончании использования выдаленную ему память следует прямо или косвенно освободить. Чтобы сделать это прямо, вызовите его метод Dispose в блоке try/catch. Чтобы сделать это косвенно, используйте языковые конструкции, такие как using (в C#) или Using (в Visual Basic). Дополнительные сведения см. в разделе "Использование объекта, реализующего IDisposable" в статье об интерфейсе IDisposable.

BufferedStream может быть составлен вокруг определенных типов потоков. Он предоставляет реализации для чтения и записи байтов в базовый источник данных или репозиторий. Используйте BinaryReader и BinaryWriter для чтения и записи других типов данных. BufferedStream предназначен для предотвращения замедления входных и выходных данных буфера, если буфер не нужен. Если вы всегда читаете и записываете размеры, превышающие размер внутреннего буфера, может BufferedStream даже не выделять внутренний буфер. BufferedStream также буферы считывают и записываются в общий буфер. Предполагается, что вы почти всегда будете выполнять ряд операций чтения или записи, но редко чередуются между ними.

Конструкторы

BufferedStream(Stream)

Инициализирует новый экземпляр класса BufferedStream со стандартным размером буфера 4096 байт.

BufferedStream(Stream, Int32)

Инициализирует новый экземпляр класса BufferedStream с заданным размером буфера.

Свойства

BufferSize

Возвращает размер буфера в байтах для этого буферизованного потока.

CanRead

Возвращает значение, определяющее в текущем потоке наличие поддержки операций чтения.

CanSeek

Возвращает значение, определяющее в текущем потоке наличие поддержки операций поиска.

CanTimeout

Возвращает значение, которое показывает, может ли для данного потока истечь время ожидания.

(Унаследовано от Stream)
CanWrite

Возвращает значение, определяющее в текущем потоке наличие поддержки операций записи.

Length

Возвращает длину потока в байтах.

Position

Возвращает позицию в текущем потоке.

ReadTimeout

Возвращает или задает значение в миллисекундах, определяющее период времени, отведенного потоку на выполнение операции чтения.

(Унаследовано от Stream)
UnderlyingStream

Возвращает базовый экземпляр Stream для этого буферизованного потока.

WriteTimeout

Возвращает или задает значение в миллисекундах, определяющее период времени, отведенного потоку на выполнение операции записи.

(Унаследовано от Stream)

Методы

BeginRead(Byte[], Int32, Int32, AsyncCallback, Object)

Начинает операцию асинхронного чтения. (Рекомендуется использовать ReadAsync(Byte[], Int32, Int32, CancellationToken).)

BeginRead(Byte[], Int32, Int32, AsyncCallback, Object)

Начинает операцию асинхронного чтения. (Рекомендуется использовать ReadAsync(Byte[], Int32, Int32).)

(Унаследовано от Stream)
BeginWrite(Byte[], Int32, Int32, AsyncCallback, Object)

Начинает операцию асинхронной записи. (Рекомендуется использовать WriteAsync(Byte[], Int32, Int32, CancellationToken).)

BeginWrite(Byte[], Int32, Int32, AsyncCallback, Object)

Начинает операцию асинхронной записи. (Рекомендуется использовать WriteAsync(Byte[], Int32, Int32).)

(Унаследовано от Stream)
Close()

Закрывает поток и освобождает все ресурсы (особенно системные ресурсы, например, сокеты и дескрипторы файлов), связанные с текущим буферизованным потоком.

Close()

Закрывает текущий поток и отключает все ресурсы (например, сокеты и файловые дескрипторы), связанные с текущим потоком. Вместо вызова данного метода, убедитесь в том, что поток надлежащим образом ликвидирован.

(Унаследовано от Stream)
CopyTo(Stream)

Считывает байты из текущего потока и записывает их в другой поток. Обе позиции потоков перемещаются по количеству скопированных байтов.

(Унаследовано от Stream)
CopyTo(Stream, Int32)

Считывает байты из текущего буферизованного потока и записывает их в другой поток.

CopyTo(Stream, Int32)

Считывает байты из текущего потока и записывает их в другой поток, используя указанный размер буфера. Обе позиции потоков перемещаются по количеству скопированных байтов.

(Унаследовано от Stream)
CopyToAsync(Stream)

Асинхронно считывает байты из текущего потока и записывает их в другой поток. Обе позиции потоков перемещаются по количеству скопированных байтов.

(Унаследовано от Stream)
CopyToAsync(Stream, CancellationToken)

Асинхронно считывает байты из текущего потока и записывает их в другой поток, используя указанный токен отмены. Обе позиции потоков перемещаются по количеству скопированных байтов.

(Унаследовано от Stream)
CopyToAsync(Stream, Int32)

Асинхронно считывает байты из текущего потока и записывает их в другой поток, используя указанный размер буфера. Обе позиции потоков перемещаются по количеству скопированных байтов.

(Унаследовано от Stream)
CopyToAsync(Stream, Int32, CancellationToken)

Асинхронно считывает байты из текущего буферизованного потока и записывает их в другой поток, используя указанный размер буфера и токен отмены.

CopyToAsync(Stream, Int32, CancellationToken)

Асинхронно считывает байты из текущего потока и записывает их в другой поток, используя указанный размер буфера и токен отмены. Обе позиции потоков перемещаются по количеству скопированных байтов.

(Унаследовано от Stream)
CreateObjRef(Type)

Создает объект, который содержит всю необходимую информацию для создания прокси-сервера, используемого для взаимодействия с удаленным объектом.

(Унаследовано от MarshalByRefObject)
CreateWaitHandle()
Является устаревшей.
Является устаревшей.
Является устаревшей.

Выделяет объект WaitHandle.

(Унаследовано от Stream)
Dispose()

Освобождает все ресурсы, занятые модулем Stream.

(Унаследовано от Stream)
Dispose(Boolean)

Освобождает неуправляемые ресурсы, используемые объектом Stream, а при необходимости освобождает также управляемые ресурсы.

(Унаследовано от Stream)
DisposeAsync()

Асинхронно освобождает неуправляемые ресурсы, используемые буферизованным потоком.

DisposeAsync()

Асинхронно освобождает неуправляемые ресурсы, используемые классом Stream.

(Унаследовано от Stream)
EndRead(IAsyncResult)

Ожидает завершения отложенной асинхронной операции чтения. (Рекомендуется использовать ReadAsync(Byte[], Int32, Int32, CancellationToken).)

EndRead(IAsyncResult)

Ожидает завершения отложенного асинхронного чтения. (Рекомендуется использовать ReadAsync(Byte[], Int32, Int32).)

(Унаследовано от Stream)
EndWrite(IAsyncResult)

Завершает асинхронную операцию записи и блокирует до тех пор, пока не будет завершена операция ввода-вывода. (Рекомендуется использовать WriteAsync(Byte[], Int32, Int32, CancellationToken).)

EndWrite(IAsyncResult)

Заканчивает операцию асинхронной записи. (Рекомендуется использовать WriteAsync(Byte[], Int32, Int32).)

(Унаследовано от Stream)
Equals(Object)

Определяет, равен ли указанный объект текущему объекту.

(Унаследовано от Object)
Flush()

Очищает все буферы для этого потока и приводит к записи всех буферизованных данных в базовое устройство.

FlushAsync()

Асинхронно очищает все буферы для этого потока и вызывает запись всех буферизованных данных в базовое устройство.

(Унаследовано от Stream)
FlushAsync(CancellationToken)

Асинхронно очищает все буферы данного потока, вызывает запись буферизованных данных в базовое устройство и отслеживает запросы отмены.

FlushAsync(CancellationToken)

Асинхронно очищает все буферы данного потока, вызывает запись буферизованных данных в базовое устройство и отслеживает запросы отмены.

(Унаследовано от Stream)
GetHashCode()

Служит хэш-функцией по умолчанию.

(Унаследовано от Object)
GetLifetimeService()
Является устаревшей.

Извлекает объект обслуживания во время существования, который управляет политикой времени существования данного экземпляра.

(Унаследовано от MarshalByRefObject)
GetType()

Возвращает объект Type для текущего экземпляра.

(Унаследовано от Object)
InitializeLifetimeService()
Является устаревшей.

Получает объект службы времени существования для управления политикой времени существования для этого экземпляра.

(Унаследовано от MarshalByRefObject)
MemberwiseClone()

Создает неполную копию текущего объекта Object.

(Унаследовано от Object)
MemberwiseClone(Boolean)

Создает неполную копию текущего объекта MarshalByRefObject.

(Унаследовано от MarshalByRefObject)
ObjectInvariant()
Является устаревшей.

Обеспечивает поддержку для Contract.

(Унаследовано от Stream)
Read(Byte[], Int32, Int32)

Копирует байты из текущего буферизованного потока в массив.

Read(Span<Byte>)

Копирует байты из текущего буферизованного потока в диапазон байтов и перемещает позицию в буферизованном потоке вперед на количество прочитанных байтов.

Read(Span<Byte>)

При переопределении в производном классе считывает последовательность байтов из текущего потока и перемещает позицию в потоке на число считанных байтов.

(Унаследовано от Stream)
ReadAsync(Byte[], Int32, Int32)

Асинхронно считывает последовательность байтов из текущего потока и перемещает позицию внутри потока на число считанных байтов.

(Унаследовано от Stream)
ReadAsync(Byte[], Int32, Int32, CancellationToken)

Асинхронно считывает последовательность байтов из текущего потока, перемещает позицию в потоке на число считанных байтов и отслеживает запросы отмены.

ReadAsync(Byte[], Int32, Int32, CancellationToken)

Асинхронно считывает последовательность байтов из текущего потока, перемещает позицию в потоке на число считанных байтов и отслеживает запросы отмены.

(Унаследовано от Stream)
ReadAsync(Memory<Byte>, CancellationToken)

Асинхронно считывает последовательность байтов из текущего буферизованного потока и перемещает позицию внутри буферизованного потока на число считанных байтов.

ReadAsync(Memory<Byte>, CancellationToken)

Асинхронно считывает последовательность байтов из текущего потока, перемещает позицию в потоке на число считанных байтов и отслеживает запросы отмены.

(Унаследовано от Stream)
ReadAtLeast(Span<Byte>, Int32, Boolean)

Считывает по крайней мере минимальное количество байтов из текущего потока и перемещает позицию в потоке на число прочитанных байтов.

(Унаследовано от Stream)
ReadAtLeastAsync(Memory<Byte>, Int32, Boolean, CancellationToken)

Асинхронно считывает по крайней мере минимальное количество байтов из текущего потока, перемещает позицию в потоке на число прочитанных байтов и отслеживает запросы на отмену.

(Унаследовано от Stream)
ReadByte()

Считывает байт из базового потока и возвращает байт, приведенный к int, или значение -1 при попытке чтения из конца потока.

ReadExactly(Byte[], Int32, Int32)

Считывает count число байтов из текущего потока и перемещает позицию в потоке.

(Унаследовано от Stream)
ReadExactly(Span<Byte>)

Считывает байты из текущего потока и перемещает позицию в потоке до buffer заполнения.

(Унаследовано от Stream)
ReadExactlyAsync(Byte[], Int32, Int32, CancellationToken)

Асинхронно считывает count количество байтов из текущего потока, перемещает позицию в потоке и отслеживает запросы на отмену.

(Унаследовано от Stream)
ReadExactlyAsync(Memory<Byte>, CancellationToken)

Асинхронно считывает байты из текущего потока, перемещает позицию в потоке до buffer заполнения и отслеживает запросы на отмену.

(Унаследовано от Stream)
Seek(Int64, SeekOrigin)

Задает позицию в текущем буферизованном потоке.

SetLength(Int64)

Задает длину буферизованного потока.

ToString()

Возвращает строку, представляющую текущий объект.

(Унаследовано от Object)
Write(Byte[], Int32, Int32)

Копирует байты в буферизованный поток и перемещает текущую позицию в буферизованном потоке вперед на количество записанных байтов.

Write(ReadOnlySpan<Byte>)

Записывает последовательность байтов в текущий буферизованный поток и перемещает текущую позицию внутри буферизованного потока на число записанных байтов.

Write(ReadOnlySpan<Byte>)

При переопределении в производном классе записывает последовательность байтов в текущий поток и перемещает текущую позицию в нем вперед на число записанных байтов.

(Унаследовано от Stream)
WriteAsync(Byte[], Int32, Int32)

Асинхронно записывает последовательность байтов в текущий поток и перемещает текущую позицию внутри потока на число записанных байтов.

(Унаследовано от Stream)
WriteAsync(Byte[], Int32, Int32, CancellationToken)

Асинхронно записывает последовательность байтов в текущий поток, перемещает текущую позицию внутри потока на число записанных байтов и отслеживает запросы отмены.

WriteAsync(Byte[], Int32, Int32, CancellationToken)

Асинхронно записывает последовательность байтов в текущий поток, перемещает текущую позицию внутри потока на число записанных байтов и отслеживает запросы отмены.

(Унаследовано от Stream)
WriteAsync(ReadOnlyMemory<Byte>, CancellationToken)

Асинхронно записывает последовательность байтов в текущий буферизованный поток, перемещает текущую позицию внутри буферизованного потока на число записанных байтов и отслеживает запросы отмены.

WriteAsync(ReadOnlyMemory<Byte>, CancellationToken)

Асинхронно записывает последовательность байтов в текущий поток, перемещает текущую позицию внутри потока на число записанных байтов и отслеживает запросы отмены.

(Унаследовано от Stream)
WriteByte(Byte)

Записывает байт в текущую позицию буферизованного потока.

Явные реализации интерфейса

IDisposable.Dispose()

Освобождает все ресурсы, занятые модулем Stream.

(Унаследовано от Stream)

Методы расширения

ConfigureAwait(IAsyncDisposable, Boolean)

Настраивает способ выполнения ожиданий для задач, возвращаемых из асинхронного высвобождаемого объекта.

Применяется к

См. также раздел