SocketAsyncEventArgs Klas
Definitie
Belangrijk
Bepaalde informatie heeft betrekking op een voorlopige productversie die aanzienlijk kan worden gewijzigd voordat deze wordt uitgebracht. Microsoft biedt geen enkele expliciete of impliciete garanties met betrekking tot de informatie die hier wordt verstrekt.
Vertegenwoordigt een asynchrone socketbewerking.
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
- Overname
- Implementeringen
Voorbeelden
In het volgende codevoorbeeld wordt de verbindingslogica geïmplementeerd voor de socketserver die gebruikmaakt van de SocketAsyncEventArgs klasse. Nadat u een verbinding hebt geaccepteerd, worden alle gegevens die van de client worden gelezen, teruggestuurd naar de client. Het lees- en echopatroon naar het clientpatroon wordt voortgezet totdat de verbinding met de client wordt verbroken. De BufferManager-klasse die in dit voorbeeld wordt gebruikt, wordt weergegeven in het codevoorbeeld voor de SetBuffer(Byte[], Int32, Int32) methode. De klasse SocketAsyncEventArgsPool die in dit voorbeeld wordt gebruikt, wordt weergegeven in het codevoorbeeld voor de SocketAsyncEventArgs constructor.
// 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);
}
}
Opmerkingen
De SocketAsyncEventArgs klasse maakt deel uit van een reeks verbeteringen aan de System.Net.Sockets.Socket klasse die een alternatief asynchroon patroon bieden dat kan worden gebruikt door gespecialiseerde sockettoepassingen met hoge prestaties. Deze klasse is speciaal ontworpen voor netwerkservertoepassingen waarvoor hoge prestaties zijn vereist. Een toepassing kan het verbeterde asynchrone patroon uitsluitend gebruiken of alleen in gerichte hot-gebieden (bijvoorbeeld bij het ontvangen van grote hoeveelheden gegevens).
De belangrijkste functie van deze verbeteringen is het vermijden van de herhaalde toewijzing en synchronisatie van objecten tijdens asynchrone socket I/O van grote volumes. Voor het ontwerppatroon Begin/Einde dat momenteel door de System.Net.Sockets.Socket klasse wordt geïmplementeerd, moet een System.IAsyncResult object worden toegewezen voor elke asynchrone socketbewerking.
In de nieuwe System.Net.Sockets.Socket klasseverbeteringen worden asynchrone socketbewerkingen beschreven door herbruikbare SocketAsyncEventArgs objecten die door de toepassing worden toegewezen en onderhouden. Krachtige sockettoepassingen kennen het beste de hoeveelheid overlappende socketbewerkingen die moeten worden voortgezet. De toepassing kan zoveel objecten SocketAsyncEventArgs maken die nodig zijn. Als een servertoepassing bijvoorbeeld te allen tijde 15 socket-acceptbewerkingen moet hebben om binnenkomende clientverbindingssnelheden te ondersteunen, kunnen er 15 herbruikbare SocketAsyncEventArgs objecten voor dat doel worden toegewezen.
Het patroon voor het uitvoeren van een asynchrone socketbewerking met deze klasse bestaat uit de volgende stappen:
Wijs een nieuw SocketAsyncEventArgs contextobject toe of ontvang een gratis object uit een groep toepassingen.
Stel eigenschappen voor het contextobject in op de bewerking die moet worden uitgevoerd (de callbackmethode voor voltooiing, de gegevensbuffer, de offset in de buffer en de maximale hoeveelheid gegevens die moet worden overgedragen, bijvoorbeeld).
Roep de juiste socketmethode (xxxAsync) aan om de asynchrone bewerking te initiëren.
Als de asynchrone socketmethode (xxxAsync) waar retourneert, voert u in de callback een query uit op de contexteigenschappen voor de voltooiingsstatus.
Als de asynchrone socketmethode (xxxAsync) onwaar retourneert, is de bewerking synchroon voltooid. De contexteigenschappen kunnen worden opgevraagd voor het bewerkingsresultaat.
Gebruik de context voor een andere bewerking opnieuw, plaats deze weer in de pool of verwijder deze.
De levensduur van het nieuwe contextobject voor asynchrone socketbewerkingen wordt bepaald door verwijzingen door de toepassingscode en asynchrone I/O-verwijzingen. Het is niet nodig voor de toepassing om een verwijzing naar een asynchroon socketbewerkingscontextobject te behouden nadat deze als parameter is verzonden naar een van de asynchrone socketbewerkingsmethoden. Er wordt naar verwezen totdat de callback voor voltooiing retourneert. Het is echter voordelig voor de toepassing om de verwijzing naar de context te behouden, zodat deze opnieuw kan worden gebruikt voor een toekomstige asynchrone socketbewerking.
Constructors
| Name | Description |
|---|---|
| SocketAsyncEventArgs() |
Hiermee maakt u een leeg SocketAsyncEventArgs exemplaar. |
Eigenschappen
| Name | Description |
|---|---|
| AcceptSocket |
Hiermee haalt u de socket op of stelt u de socket in die is gemaakt voor het accepteren van een verbinding met een asynchrone socketmethode. |
| Buffer |
Hiermee haalt u de gegevensbuffer op die moet worden gebruikt met een asynchrone socketmethode. |
| BufferList |
Hiermee wordt een matrix van gegevensbuffers opgehaald of ingesteld voor gebruik met een asynchrone socketmethode. |
| BytesTransferred |
Hiermee haalt u het aantal overgedragen bytes op in de socketbewerking. |
| ConnectByNameError |
Hiermee wordt de uitzondering opgehaald in het geval van een verbindingsfout bij gebruik van een DnsEndPoint verbinding. |
| ConnectSocket |
Het gemaakte en verbonden Socket object na voltooiing van de ConnectAsync methode. |
| Count |
Hiermee wordt de maximale hoeveelheid gegevens, in bytes, opgehaald voor het verzenden of ontvangen van gegevens in een asynchrone bewerking. |
| DisconnectReuseSocket |
Hiermee haalt u een waarde op die aangeeft of socket opnieuw kan worden gebruikt na een verbroken bewerking. |
| LastOperation |
Hiermee wordt het type socketbewerking opgehaald dat het laatst is uitgevoerd met dit contextobject. |
| MemoryBuffer |
Hiermee haalt u het geheugengebied op dat moet worden gebruikt als buffer met een asynchrone socketmethode. |
| Offset |
Hiermee haalt u de offset in bytes op in de gegevensbuffer waarnaar wordt verwezen door de Buffer eigenschap. |
| ReceiveMessageFromPacketInfo |
Hiermee haalt u het IP-adres en de interface van een ontvangen pakket op. |
| RemoteEndPoint |
Hiermee wordt het externe IP-eindpunt voor een asynchrone bewerking ophaalt of ingesteld. |
| SendPacketsElements |
Hiermee kunt u een matrix van buffers ophalen of instellen die moeten worden verzonden voor een asynchrone bewerking die door de SendPacketsAsync(SocketAsyncEventArgs) methode wordt gebruikt. |
| SendPacketsFlags |
Haalt een bitsgewijze combinatie van TransmitFileOptions waarden op of stelt deze in voor een asynchrone bewerking die door de SendPacketsAsync(SocketAsyncEventArgs) methode wordt gebruikt. |
| SendPacketsSendSize |
Hiermee wordt de grootte, in bytes, van het gegevensblok opgehaald of ingesteld dat in de verzendbewerking wordt gebruikt. |
| SocketClientAccessPolicyProtocol |
Verouderd.
Hiermee haalt u het protocol op dat moet worden gebruikt voor het downloaden van het socket-clienttoegangsbeleidsbestand. |
| SocketError |
Hiermee haalt u het resultaat van de asynchrone socketbewerking op of stelt u deze in. |
| SocketFlags |
Hiermee worden de resultaten van een asynchrone socketbewerking opgehaald of wordt het gedrag van een asynchrone bewerking ingesteld. |
| UserToken |
Hiermee haalt u een gebruiker of toepassingsobject op dat is gekoppeld aan deze asynchrone socketbewerking. |
Methoden
| Name | Description |
|---|---|
| Dispose() |
Publiceert de niet-beheerde resources die door het SocketAsyncEventArgs exemplaar worden gebruikt en verwijdert desgewenst de beheerde resources. |
| Equals(Object) |
Bepaalt of het opgegeven object gelijk is aan het huidige object. (Overgenomen van Object) |
| Finalize() |
Hiermee worden resources vrijgemaakt die door de SocketAsyncEventArgs klasse worden gebruikt. |
| GetHashCode() |
Fungeert als de standaardhashfunctie. (Overgenomen van Object) |
| GetType() |
Hiermee haalt u de Type huidige instantie op. (Overgenomen van Object) |
| MemberwiseClone() |
Hiermee maakt u een ondiepe kopie van de huidige Object. (Overgenomen van Object) |
| OnCompleted(SocketAsyncEventArgs) |
Vertegenwoordigt een methode die wordt aangeroepen wanneer een asynchrone bewerking is voltooid. |
| SetBuffer(Byte[], Int32, Int32) |
Hiermee stelt u de gegevensbuffer in voor gebruik met een asynchrone socketmethode. |
| SetBuffer(Int32, Int32) |
Hiermee stelt u de gegevensbuffer in voor gebruik met een asynchrone socketmethode. |
| SetBuffer(Memory<Byte>) |
Hiermee stelt u het geheugengebied in dat moet worden gebruikt als buffer met een asynchrone socketmethode. |
| ToString() |
Retourneert een tekenreeks die het huidige object vertegenwoordigt. (Overgenomen van Object) |
gebeurtenis
| Name | Description |
|---|---|
| Completed |
De gebeurtenis die wordt gebruikt om een asynchrone bewerking te voltooien. |
Van toepassing op
Zie ook
- IAsyncResult
- Socket
- AcceptAsync(SocketAsyncEventArgs)
- ConnectAsync(SocketAsyncEventArgs)
- DisconnectAsync(SocketAsyncEventArgs)
- ReceiveAsync(SocketAsyncEventArgs)
- ReceiveFromAsync(SocketAsyncEventArgs)
- ReceiveMessageFromAsync(SocketAsyncEventArgs)
- SendAsync(SocketAsyncEventArgs)
- SendPacketsAsync(SocketAsyncEventArgs)
- SendToAsync(SocketAsyncEventArgs)
- Netwerkprogrammering in het .NET Framework
- Netwerktracering in .NET Framework
- Prestatieverbeteringen in sockets in versie 3.5