SocketAsyncEventArgs Klass
Definition
Viktigt
En del information gäller för förhandsversionen av en produkt och kan komma att ändras avsevärt innan produkten blir allmänt tillgänglig. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, avseende informationen som visas här.
Representerar en asynkron socketåtgärd.
public ref class SocketAsyncEventArgs : EventArgs, IDisposable
public class SocketAsyncEventArgs : EventArgs, IDisposable
type SocketAsyncEventArgs = class
inherit EventArgs
interface IDisposable
Public Class SocketAsyncEventArgs
Inherits EventArgs
Implements IDisposable
- Arv
- Implementeringar
Exempel
I följande kodexempel implementeras anslutningslogik för socketservern som använder SocketAsyncEventArgs klassen. När du har accepterat en anslutning skickas alla data som läss från klienten tillbaka till klienten. Läsningen och ekot tillbaka till klientmönstret fortsätter tills klienten kopplas från. Klassen BufferManager som används i det här exemplet visas i kodexemplet för SetBuffer(Byte[], Int32, Int32) metoden. Klassen SocketAsyncEventArgsPool som används i det här exemplet visas i kodexemplet för SocketAsyncEventArgs konstruktorn.
// Implements the connection logic for the socket server.
// After accepting a connection, all data read from the client
// is sent back to the client. The read and echo back to the client pattern
// is continued until the client disconnects.
class Server
{
private int m_numConnections; // the maximum number of connections the sample is designed to handle simultaneously
private int m_receiveBufferSize;// buffer size to use for each socket I/O operation
BufferManager m_bufferManager; // represents a large reusable set of buffers for all socket operations
const int opsToPreAlloc = 2; // read, write (don't alloc buffer space for accepts)
Socket listenSocket; // the socket used to listen for incoming connection requests
// pool of reusable SocketAsyncEventArgs objects for write, read and accept socket operations
SocketAsyncEventArgsPool m_readWritePool;
int m_totalBytesRead; // counter of the total # bytes received by the server
int m_numConnectedSockets; // the total number of clients connected to the server
Semaphore m_maxNumberAcceptedClients;
// Create an uninitialized server instance.
// To start the server listening for connection requests
// call the Init method followed by Start method
//
// <param name="numConnections">the maximum number of connections the sample is designed to handle simultaneously</param>
// <param name="receiveBufferSize">buffer size to use for each socket I/O operation</param>
public Server(int numConnections, int receiveBufferSize)
{
m_totalBytesRead = 0;
m_numConnectedSockets = 0;
m_numConnections = numConnections;
m_receiveBufferSize = receiveBufferSize;
// allocate buffers such that the maximum number of sockets can have one outstanding read and
//write posted to the socket simultaneously
m_bufferManager = new BufferManager(receiveBufferSize * numConnections * opsToPreAlloc,
receiveBufferSize);
m_readWritePool = new SocketAsyncEventArgsPool(numConnections);
m_maxNumberAcceptedClients = new Semaphore(numConnections, numConnections);
}
// Initializes the server by preallocating reusable buffers and
// context objects. These objects do not need to be preallocated
// or reused, but it is done this way to illustrate how the API can
// easily be used to create reusable objects to increase server performance.
//
public void Init()
{
// Allocates one large byte buffer which all I/O operations use a piece of. This gaurds
// against memory fragmentation
m_bufferManager.InitBuffer();
// preallocate pool of SocketAsyncEventArgs objects
SocketAsyncEventArgs readWriteEventArg;
for (int i = 0; i < m_numConnections; i++)
{
//Pre-allocate a set of reusable SocketAsyncEventArgs
readWriteEventArg = new SocketAsyncEventArgs();
readWriteEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
// assign a byte buffer from the buffer pool to the SocketAsyncEventArg object
m_bufferManager.SetBuffer(readWriteEventArg);
// add SocketAsyncEventArg to the pool
m_readWritePool.Push(readWriteEventArg);
}
}
// Starts the server such that it is listening for
// incoming connection requests.
//
// <param name="localEndPoint">The endpoint which the server will listening
// for connection requests on</param>
public void Start(IPEndPoint localEndPoint)
{
// create the socket which listens for incoming connections
listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(localEndPoint);
// start the server with a listen backlog of 100 connections
listenSocket.Listen(100);
// post accepts on the listening socket
SocketAsyncEventArgs acceptEventArg = new SocketAsyncEventArgs();
acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
StartAccept(acceptEventArg);
//Console.WriteLine("{0} connected sockets with one outstanding receive posted to each....press any key", m_outstandingReadCount);
Console.WriteLine("Press any key to terminate the server process....");
Console.ReadKey();
}
// Begins an operation to accept a connection request from the client
//
// <param name="acceptEventArg">The context object to use when issuing
// the accept operation on the server's listening socket</param>
public void StartAccept(SocketAsyncEventArgs acceptEventArg)
{
// loop while the method completes synchronously
bool willRaiseEvent = false;
while (!willRaiseEvent)
{
m_maxNumberAcceptedClients.WaitOne();
// socket must be cleared since the context object is being reused
acceptEventArg.AcceptSocket = null;
willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);
if (!willRaiseEvent)
{
ProcessAccept(acceptEventArg);
}
}
}
// This method is the callback method associated with Socket.AcceptAsync
// operations and is invoked when an accept operation is complete
//
void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
ProcessAccept(e);
// Accept the next connection request
StartAccept(e);
}
private void ProcessAccept(SocketAsyncEventArgs e)
{
Interlocked.Increment(ref m_numConnectedSockets);
Console.WriteLine("Client connection accepted. There are {0} clients connected to the server",
m_numConnectedSockets);
// Get the socket for the accepted client connection and put it into the
//ReadEventArg object user token
SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop();
readEventArgs.UserToken = e.AcceptSocket;
// As soon as the client is connected, post a receive to the connection
bool willRaiseEvent = e.AcceptSocket.ReceiveAsync(readEventArgs);
if (!willRaiseEvent)
{
ProcessReceive(readEventArgs);
}
}
// This method is called whenever a receive or send operation is completed on a socket
//
// <param name="e">SocketAsyncEventArg associated with the completed receive operation</param>
void IO_Completed(object sender, SocketAsyncEventArgs e)
{
// determine which type of operation just completed and call the associated handler
switch (e.LastOperation)
{
case SocketAsyncOperation.Receive:
ProcessReceive(e);
break;
case SocketAsyncOperation.Send:
ProcessSend(e);
break;
default:
throw new ArgumentException("The last operation completed on the socket was not a receive or send");
}
}
// This method is invoked when an asynchronous receive operation completes.
// If the remote host closed the connection, then the socket is closed.
// If data was received then the data is echoed back to the client.
//
private void ProcessReceive(SocketAsyncEventArgs e)
{
// check if the remote host closed the connection
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
//increment the count of the total bytes receive by the server
Interlocked.Add(ref m_totalBytesRead, e.BytesTransferred);
Console.WriteLine("The server has read a total of {0} bytes", m_totalBytesRead);
//echo the data received back to the client
e.SetBuffer(e.Offset, e.BytesTransferred);
Socket socket = (Socket)e.UserToken;
bool willRaiseEvent = socket.SendAsync(e);
if (!willRaiseEvent)
{
ProcessSend(e);
}
}
else
{
CloseClientSocket(e);
}
}
// This method is invoked when an asynchronous send operation completes.
// The method issues another receive on the socket to read any additional
// data sent from the client
//
// <param name="e"></param>
private void ProcessSend(SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
// done echoing data back to the client
Socket socket = (Socket)e.UserToken;
// read the next block of data send from the client
bool willRaiseEvent = socket.ReceiveAsync(e);
if (!willRaiseEvent)
{
ProcessReceive(e);
}
}
else
{
CloseClientSocket(e);
}
}
private void CloseClientSocket(SocketAsyncEventArgs e)
{
Socket socket = (Socket)e.UserToken;
// close the socket associated with the client
try
{
socket.Shutdown(SocketShutdown.Send);
}
// throws if client process has already closed
catch (Exception) { }
socket.Close();
// decrement the counter keeping track of the total number of clients connected to the server
Interlocked.Decrement(ref m_numConnectedSockets);
// Free the SocketAsyncEventArg so they can be reused by another client
m_readWritePool.Push(e);
m_maxNumberAcceptedClients.Release();
Console.WriteLine("A client has been disconnected from the server. There are {0} clients connected to the server", m_numConnectedSockets);
}
}
Kommentarer
Klassen SocketAsyncEventArgs är en del av en uppsättning förbättringar System.Net.Sockets.Socket av klassen som ger ett alternativt asynkront mönster som kan användas av specialiserade socketprogram med höga prestanda. Den här klassen har utformats särskilt för nätverksserverprogram som kräver höga prestanda. Ett program kan använda det förbättrade asynkrona mönstret uteslutande eller endast i riktade heta områden (till exempel när man tar emot stora mängder data).
Huvudfunktionen i dessa förbättringar är att undvika upprepad allokering och synkronisering av objekt under asynkron socket-I/O med hög volym. Designmönstret Begin/End som för närvarande implementeras av System.Net.Sockets.Socket klassen kräver att ett System.IAsyncResult objekt allokeras för varje asynkron socketåtgärd.
I de nya System.Net.Sockets.Socket klassförbättringarna beskrivs asynkrona socketåtgärder av återanvändbara SocketAsyncEventArgs objekt som allokeras och underhålls av programmet. Socketprogram med höga prestanda vet bäst hur mycket överlappande socketåtgärder som måste upprätthållas. Programmet kan skapa så många av de SocketAsyncEventArgs objekt som det behöver. Om till exempel ett serverprogram måste ha 15 socket acceptera åtgärder som är utestående hela tiden för att stödja inkommande klientanslutningshastigheter, kan det allokera 15 återanvändbara SocketAsyncEventArgs objekt för det ändamålet.
Mönstret för att utföra en asynkron socketåtgärd med den här klassen består av följande steg:
Allokera ett nytt SocketAsyncEventArgs kontextobjekt eller hämta ett kostnadsfritt objekt från en programpool.
Ange egenskaper för kontextobjektet till den åtgärd som ska utföras (metoden för att slutföra återanropet, databufferten, förskjutningen till bufferten och den maximala mängden data som ska överföras, till exempel).
Anropa lämplig socketmetod (xxxAsync) för att initiera den asynkrona åtgärden.
Om den asynkrona socketmetoden (xxxAsync) returnerar sant frågar du kontextegenskaperna för slutförandestatus i återanropet.
Om den asynkrona socketmetoden (xxxAsync) returnerar false slutfördes åtgärden synkront. Kontextegenskaperna kan efterfrågas för åtgärdsresultatet.
Återanvänd kontexten för en annan åtgärd, sätt tillbaka den i poolen eller ta bort den.
Livslängden för det nya asynkrona socketåtgärdskontextobjektet bestäms av referenser av programkoden och asynkrona I/O-referenser. Det är inte nödvändigt att programmet behåller en referens till ett asynkront socketåtgärdskontextobjekt efter att det har skickats som en parameter till någon av de asynkrona socketåtgärdsmetoderna. Den förblir refererad tills återanropet för slutförande returneras. Det är dock fördelaktigt för programmet att behålla referensen till kontexten så att den kan återanvändas för en framtida asynkron socketåtgärd.
Konstruktorer
| Name | Description |
|---|---|
| SocketAsyncEventArgs() |
Skapar en tom SocketAsyncEventArgs instans. |
| SocketAsyncEventArgs(Boolean) |
Initierar SocketAsyncEventArgs. |
Egenskaper
| Name | Description |
|---|---|
| AcceptSocket |
Hämtar eller ställer in socketen som ska användas eller den socket som skapats för att acceptera en anslutning med en asynkron socketmetod. |
| Buffer |
Hämtar databufferten som ska användas med en asynkron socketmetod. |
| BufferList |
Hämtar eller anger en matris med databuffertar som ska användas med en asynkron socketmetod. |
| BytesTransferred |
Hämtar antalet byte som överförs i socketåtgärden. |
| ConnectByNameError |
Hämtar undantaget i händelse av ett anslutningsfel när en DnsEndPoint användes. |
| ConnectSocket |
Det skapade och anslutna Socket objektet efter att metoden har slutförts ConnectAsync . |
| Count |
Hämtar den maximala mängden data i byte som ska skickas eller tas emot i en asynkron åtgärd. |
| DisconnectReuseSocket |
Hämtar eller anger ett värde som anger om socket kan återanvändas efter en frånkopplingsåtgärd. |
| LastOperation |
Hämtar den typ av socketåtgärd som senast utfördes med det här kontextobjektet. |
| MemoryBuffer |
Hämtar den minnesregion som ska användas som buffert med en asynkron socketmetod. |
| Offset |
Hämtar förskjutningen i byte till den databuffert som refereras av Buffer egenskapen. |
| ReceiveMessageFromPacketInfo |
Hämtar IP-adressen och gränssnittet för ett mottaget paket. |
| RemoteEndPoint |
Hämtar eller anger fjärr-IP-slutpunkten för en asynkron åtgärd. |
| SendPacketsElements |
Hämtar eller anger en matris med buffertar som ska skickas för en asynkron åtgärd som används av SendPacketsAsync(SocketAsyncEventArgs) metoden. |
| SendPacketsFlags |
Hämtar eller anger en bitvis kombination av TransmitFileOptions värden för en asynkron åtgärd som används av SendPacketsAsync(SocketAsyncEventArgs) metoden. |
| SendPacketsSendSize |
Hämtar eller anger storleken, i byte, på datablocket som används i sändningsåtgärden. |
| SocketClientAccessPolicyProtocol |
Föråldrad.
Hämtar eller anger vilket protokoll som ska användas för att ladda ned socketklientens åtkomstprincipfil. |
| SocketError |
Hämtar eller anger resultatet av den asynkrona socketåtgärden. |
| SocketFlags |
Hämtar resultatet av en asynkron socketåtgärd eller anger beteendet för en asynkron åtgärd. |
| UserToken |
Hämtar eller anger ett användar- eller programobjekt som är associerat med den här asynkrona socketåtgärden. |
Metoder
| Name | Description |
|---|---|
| Dispose() |
Frigör de ohanterade resurser som används av instansen SocketAsyncEventArgs och om du vill kan du ta bort de hanterade resurserna. |
| Equals(Object) |
Avgör om det angivna objektet är lika med det aktuella objektet. (Ärvd från Object) |
| Finalize() |
Frigör resurser som används av SocketAsyncEventArgs klassen. |
| GetHashCode() |
Fungerar som standard-hash-funktion. (Ärvd från Object) |
| GetType() |
Hämtar den aktuella instansen Type . (Ärvd från Object) |
| MemberwiseClone() |
Skapar en ytlig kopia av den aktuella Object. (Ärvd från Object) |
| OnCompleted(SocketAsyncEventArgs) |
Representerar en metod som anropas när en asynkron åtgärd slutförs. |
| SetBuffer(Byte[], Int32, Int32) |
Anger vilken databuffert som ska användas med en asynkron socketmetod. |
| SetBuffer(Int32, Int32) |
Anger vilken databuffert som ska användas med en asynkron socketmetod. |
| SetBuffer(Memory<Byte>) |
Anger den minnesregion som ska användas som en buffert med en asynkron socketmetod. |
| ToString() |
Returnerar en sträng som representerar det aktuella objektet. (Ärvd från Object) |
Händelser
| Name | Description |
|---|---|
| Completed |
Händelsen som används för att slutföra en asynkron åtgärd. |
Gäller för
Se även
- IAsyncResult
- Socket
- AcceptAsync(SocketAsyncEventArgs)
- ConnectAsync(SocketAsyncEventArgs)
- DisconnectAsync(SocketAsyncEventArgs)
- ReceiveAsync(SocketAsyncEventArgs)
- ReceiveFromAsync(SocketAsyncEventArgs)
- ReceiveMessageFromAsync(SocketAsyncEventArgs)
- SendAsync(SocketAsyncEventArgs)
- SendPacketsAsync(SocketAsyncEventArgs)
- SendToAsync(SocketAsyncEventArgs)
- Nätverksprogrammering i .NET Framework
- Nätverksspårning i .NET Framework
- Förbättringar av socketprestanda i version 3.5