SocketAsyncEventArgs Classe
Définition
Important
Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifiée avant sa publication. Microsoft exclut toute garantie, expresse ou implicite, concernant les informations fournies ici.
Représente une opération de socket asynchrone.
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
- Héritage
- Implémente
Exemples
L’exemple de code suivant implémente la logique de connexion pour le serveur de sockets qui utilise la SocketAsyncEventArgs classe. Après avoir accepté une connexion, toutes les données lues à partir du client sont renvoyées au client. La lecture et l’écho au modèle client sont poursuivies jusqu’à ce que le client se déconnecte. La classe BufferManager utilisée par cet exemple est affichée dans l’exemple de code de la SetBuffer(Byte[], Int32, Int32) méthode. La classe SocketAsyncEventArgsPool utilisée dans cet exemple est affichée dans l’exemple de code du SocketAsyncEventArgs constructeur.
// 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);
}
}
Remarques
La SocketAsyncEventArgs classe fait partie d’un ensemble d’améliorations apportées à la System.Net.Sockets.Socket classe qui fournissent un autre modèle asynchrone qui peut être utilisé par des applications de socket hautes performances spécialisées. Cette classe a été spécifiquement conçue pour les applications de serveur réseau qui nécessitent des performances élevées. Une application peut utiliser le modèle asynchrone amélioré exclusivement ou uniquement dans les zones chaudes ciblées (par exemple, lors de la réception de grandes quantités de données).
La principale fonctionnalité de ces améliorations est l’évitement de l’allocation et de la synchronisation répétées d’objets pendant les E/S de socket asynchrones à volume élevé. Le modèle de conception Begin/End actuellement implémenté par la System.Net.Sockets.Socket classe nécessite qu’un System.IAsyncResult objet soit alloué pour chaque opération de socket asynchrone.
Dans les nouvelles System.Net.Sockets.Socket améliorations de classe, les opérations de socket asynchrone sont décrites par des objets réutilisables SocketAsyncEventArgs alloués et gérés par l’application. Les applications de socket hautes performances connaissent le mieux la quantité d’opérations de socket superposées qui doivent être soutenues. L’application peut créer autant d’objets SocketAsyncEventArgs dont elle a besoin. Par exemple, si une application serveur doit avoir 15 opérations d’acceptation de socket en attente à tout moment pour prendre en charge les taux de connexion client entrants, elle peut allouer 15 objets réutilisables SocketAsyncEventArgs à cet effet.
Le modèle d’exécution d’une opération de socket asynchrone avec cette classe se compose des étapes suivantes :
Allouez un nouvel SocketAsyncEventArgs objet de contexte ou obtenez un objet gratuit à partir d’un pool d’applications.
Définissez les propriétés de l’objet de contexte sur l’opération sur le point d’être effectuée (la méthode de rappel d’achèvement, la mémoire tampon de données, le décalage dans la mémoire tampon et la quantité maximale de données à transférer, par exemple).
Appelez la méthode de socket appropriée (xxxAsync) pour lancer l’opération asynchrone.
Si la méthode de socket asynchrone (xxxAsync) retourne true, dans le rappel, interrogez les propriétés de contexte pour obtenir l’état d’achèvement.
Si la méthode de socket asynchrone (xxxAsync) retourne false, l’opération s’est terminée de façon synchrone. Les propriétés de contexte peuvent être interrogées pour le résultat de l’opération.
Réutilisez le contexte d’une autre opération, remettez-le dans le pool ou ignorez-le.
La durée de vie du nouvel objet de contexte d’opération de socket asynchrone est déterminée par les références par le code de l’application et les références d’E/S asynchrones. Il n’est pas nécessaire pour l’application de conserver une référence à un objet de contexte d’opération de socket asynchrone après son envoi en tant que paramètre à l’une des méthodes d’opération de socket asynchrone. Il reste référencé jusqu’à ce que le rappel d’achèvement retourne. Toutefois, il est avantageux pour l’application de conserver la référence au contexte afin qu’elle puisse être réutilisée pour une opération de socket asynchrone ultérieure.
Constructeurs
| Nom | Description |
|---|---|
| SocketAsyncEventArgs() |
Crée une instance vide SocketAsyncEventArgs . |
Propriétés
| Nom | Description |
|---|---|
| AcceptSocket |
Obtient ou définit le socket à utiliser ou le socket créé pour accepter une connexion avec une méthode de socket asynchrone. |
| Buffer |
Obtient la mémoire tampon de données à utiliser avec une méthode de socket asynchrone. |
| BufferList |
Obtient ou définit un tableau de mémoires tampons de données à utiliser avec une méthode de socket asynchrone. |
| BytesTransferred |
Obtient le nombre d’octets transférés dans l’opération de socket. |
| ConnectByNameError |
Obtient l’exception en cas d’échec de connexion lorsqu’une connexion DnsEndPoint a été utilisée. |
| ConnectSocket |
Objet créé et connecté Socket après la réussite de la ConnectAsync méthode. |
| Count |
Obtient la quantité maximale de données, en octets, à envoyer ou recevoir dans une opération asynchrone. |
| DisconnectReuseSocket |
Obtient ou définit une valeur qui spécifie si le socket peut être réutilisé après une opération de déconnexion. |
| LastOperation |
Obtient le type d’opération de socket le plus récemment effectué avec cet objet de contexte. |
| MemoryBuffer |
Obtient la région de mémoire à utiliser comme mémoire tampon avec une méthode de socket asynchrone. |
| Offset |
Obtient le décalage, en octets, dans la mémoire tampon de données référencée par la Buffer propriété. |
| ReceiveMessageFromPacketInfo |
Obtient l’adresse IP et l’interface d’un paquet reçu. |
| RemoteEndPoint |
Obtient ou définit le point de terminaison IP distant pour une opération asynchrone. |
| SendPacketsElements |
Obtient ou définit un tableau de mémoires tampons à envoyer pour une opération asynchrone utilisée par la SendPacketsAsync(SocketAsyncEventArgs) méthode. |
| SendPacketsFlags |
Obtient ou définit une combinaison de valeurs au niveau du TransmitFileOptions bit pour une opération asynchrone utilisée par la SendPacketsAsync(SocketAsyncEventArgs) méthode. |
| SendPacketsSendSize |
Obtient ou définit la taille, en octets, du bloc de données utilisé dans l’opération d’envoi. |
| SocketClientAccessPolicyProtocol |
Obsolète.
Obtient ou définit le protocole à utiliser pour télécharger le fichier de stratégie d’accès client de socket. |
| SocketError |
Obtient ou définit le résultat de l’opération de socket asynchrone. |
| SocketFlags |
Obtient les résultats d’une opération de socket asynchrone ou définit le comportement d’une opération asynchrone. |
| UserToken |
Obtient ou définit un objet utilisateur ou application associé à cette opération de socket asynchrone. |
Méthodes
| Nom | Description |
|---|---|
| Dispose() |
Libère les ressources non managées utilisées par l’instance SocketAsyncEventArgs et supprime éventuellement les ressources managées. |
| Equals(Object) |
Détermine si l’objet spécifié est égal à l’objet actuel. (Hérité de Object) |
| Finalize() |
Libère les ressources utilisées par la SocketAsyncEventArgs classe. |
| GetHashCode() |
Sert de fonction de hachage par défaut. (Hérité de Object) |
| GetType() |
Obtient la Type de l’instance actuelle. (Hérité de Object) |
| MemberwiseClone() |
Crée une copie superficielle du Objectactuel. (Hérité de Object) |
| OnCompleted(SocketAsyncEventArgs) |
Représente une méthode appelée lorsqu’une opération asynchrone se termine. |
| SetBuffer(Byte[], Int32, Int32) |
Définit la mémoire tampon de données à utiliser avec une méthode de socket asynchrone. |
| SetBuffer(Int32, Int32) |
Définit la mémoire tampon de données à utiliser avec une méthode de socket asynchrone. |
| SetBuffer(Memory<Byte>) |
Définit la région de mémoire à utiliser comme mémoire tampon avec une méthode de socket asynchrone. |
| ToString() |
Retourne une chaîne qui représente l’objet actuel. (Hérité de Object) |
Événements
| Nom | Description |
|---|---|
| Completed |
Événement utilisé pour effectuer une opération asynchrone. |
S’applique à
Voir aussi
- IAsyncResult
- Socket
- AcceptAsync(SocketAsyncEventArgs)
- ConnectAsync(SocketAsyncEventArgs)
- DisconnectAsync(SocketAsyncEventArgs)
- ReceiveAsync(SocketAsyncEventArgs)
- ReceiveFromAsync(SocketAsyncEventArgs)
- ReceiveMessageFromAsync(SocketAsyncEventArgs)
- SendAsync(SocketAsyncEventArgs)
- SendPacketsAsync(SocketAsyncEventArgs)
- SendToAsync(SocketAsyncEventArgs)
- Programmation réseau dans le .NET Framework
- Suivi réseau dans le .NET Framework
- Améliorations des performances du socket dans la version 3.5