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
над классом 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 и WriteBufferedStream
автоматически сохраняют буфер.
Важный
Этот тип реализует интерфейс 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() |
Считывает байт из базового потока и возвращает байтовый байт в |
ReadExactly(Byte[], Int32, Int32) |
Считывает |
ReadExactly(Span<Byte>) |
Считывает байты из текущего потока и перемещает позицию в потоке до заполнения |
ReadExactlyAsync(Byte[], Int32, Int32, CancellationToken) |
Асинхронно считывает |
ReadExactlyAsync(Memory<Byte>, CancellationToken) |
Асинхронно считывает байты из текущего потока, перемещает положение в потоке до заполнения |
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) |
Методы расширения
CopyToAsync(Stream, PipeWriter, CancellationToken) |
Асинхронно считывает байты из Stream и записывает их в указанный PipeWriterс помощью маркера отмены. |
ConfigureAwait(IAsyncDisposable, Boolean) |
Настраивает способ ожидания задач, возвращаемых из асинхронного удаления. |