SocketAsyncEventArgs Classe

Définition

Représente une opération de socket asynchrone.Represents an asynchronous socket operation.

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
SocketAsyncEventArgs
Implémente

Exemples

L’exemple de code suivant implémente la logique de connexion pour le serveur de socket qui utilise la SocketAsyncEventArgs classe.The following code example implements the connection logic for the socket server that uses the SocketAsyncEventArgs class. Après avoir accepté une connexion, toutes les données lues à partir du client sont renvoyées au client.After accepting a connection, all data read from the client is sent back to the client. La lecture et l’écho vers le modèle client sont poursuivies jusqu’à ce que le client se déconnecte.The read and echo back to the client pattern is continued until the client disconnects. La classe BufferManager utilisée par cet exemple est affichée dans l’exemple de code de la SetBuffer(Byte[], Int32, Int32) méthode.The BufferManager class that is used by this example is displayed in the code example for the SetBuffer(Byte[], Int32, Int32) method. La classe SocketAsyncEventArgsPool utilisée dans cet exemple est affichée dans l’exemple de code pour le SocketAsyncEventArgs constructeur.The SocketAsyncEventArgsPool class that is used in this example is displayed in the code example for the 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);
            readWriteEventArg.UserToken = new AsyncUserToken();

            // 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
        StartAccept(null);

        //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)
    {
        if (acceptEventArg == null)
        {
            acceptEventArg = new SocketAsyncEventArgs();
            acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
        }
        else
        {
            // socket must be cleared since the context object is being reused
            acceptEventArg.AcceptSocket = null;
        }

        m_maxNumberAcceptedClients.WaitOne();
        bool 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);
    }

    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();
        ((AsyncUserToken)readEventArgs.UserToken).Socket = 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);
        }

        // Accept the next connection request
        StartAccept(e);
    }

    // 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
        AsyncUserToken token = (AsyncUserToken)e.UserToken;
        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);
            bool willRaiseEvent = token.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
            AsyncUserToken token = (AsyncUserToken)e.UserToken;
            // read the next block of data send from the client
            bool willRaiseEvent = token.Socket.ReceiveAsync(e);
            if (!willRaiseEvent)
            {
                ProcessReceive(e);
            }
        }
        else
        {
            CloseClientSocket(e);
        }
    }

    private void CloseClientSocket(SocketAsyncEventArgs e)
    {
        AsyncUserToken token = e.UserToken as AsyncUserToken;

        // close the socket associated with the client
        try
        {
            token.Socket.Shutdown(SocketShutdown.Send);
        }
        // throws if client process has already closed
        catch (Exception) { }
        token.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 fournit un autre modèle asynchrone pouvant être utilisé par des applications de socket spécialisées très performantes.The SocketAsyncEventArgs class is part of a set of enhancements to the System.Net.Sockets.Socket class that provide an alternative asynchronous pattern that can be used by specialized high-performance socket applications. Cette classe a été spécialement conçue pour les applications de serveur réseau qui requièrent des performances élevées.This class was specifically designed for network server applications that require high performance. Une application peut utiliser le modèle asynchrone amélioré exclusivement ou uniquement dans les zones réactives ciblées (par exemple, lors de la réception de grandes quantités de données).An application can use the enhanced asynchronous pattern exclusively or only in targeted hot areas (for example, when receiving large amounts of data).

L’objectif principal de ces améliorations est d’éviter la répétition des opérations d’allocation et de synchronisation d’objets durant les processus impliquant de nombreuses entrées/sorties de socket asynchrones.The main feature of these enhancements is the avoidance of the repeated allocation and synchronization of objects during high-volume asynchronous socket I/O. Le modèle de conception Begin/End actuellement implémenté par la System.Net.Sockets.Socket classe requiert System.IAsyncResult qu’un objet soit alloué pour chaque opération de socket asynchrone.The Begin/End design pattern currently implemented by the System.Net.Sockets.Socket class requires a System.IAsyncResult object be allocated for each asynchronous socket operation.

Dans les nouvelles System.Net.Sockets.Socket améliorations de classe, les opérations de socket asynchrones sont décrites par des objets réutilisables SocketAsyncEventArgs alloués et gérés par l’application.In the new System.Net.Sockets.Socket class enhancements, asynchronous socket operations are described by reusable SocketAsyncEventArgs objects allocated and maintained by the application. Les applications de socket à hautes performances peuvent ainsi mieux évaluer le nombre d’opérations de socket superposées à conserver.High-performance socket applications know best the amount of overlapped socket operations that must be sustained. L’application peut créer autant d’objets SocketAsyncEventArgs qu’elle a besoin.The application can create as many of the SocketAsyncEventArgs objects that it needs. Par exemple, si une application serveur a besoin de 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 cette fin.For example, if a server application needs to have 15 socket accept operations outstanding at all times to support incoming client connection rates, it can allocate 15 reusable SocketAsyncEventArgs objects for that purpose.

Le modèle pour effectuer une opération de socket asynchrone avec cette classe comprend les étapes suivantes :The pattern for performing an asynchronous socket operation with this class consists of the following steps:

  1. Allouer un nouvel objet de contexte SocketAsyncEventArgs, ou en obtenir un gratuitement à partir d’un pool d’applications.Allocate a new SocketAsyncEventArgs context object, or get a free one from an application pool.

  2. 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, l’offset dans la mémoire tampon et la quantité maximale de données à transférer, par exemple).Set properties on the context object to the operation about to be performed (the completion callback method, the data buffer, the offset into the buffer, and the maximum amount of data to transfer, for example).

  3. Appeler la méthode de socket appropriée (xxxAsync) pour lancer l’opération asynchrone.Call the appropriate socket method (xxxAsync) to initiate the asynchronous operation.

  4. Si la méthode de socket asynchrone (xxxAsync) retourne la valeur true, dans le rappel, interrogez les propriétés de contexte pour obtenir l’état d’achèvement.If the asynchronous socket method (xxxAsync) returns true, in the callback, query the context properties for completion status.

  5. Si la méthode de socket asynchrone (xxxAsync) retourne la valeur false, l’opération s’est terminée de façon synchrone.If the asynchronous socket method (xxxAsync) returns false, the operation completed synchronously. L’obtention des propriétés de contexte peut être nécessaire pour le résultat de l’opération.The context properties may be queried for the operation result.

  6. Réutiliser le contexte pour une autre opération, le replacer dans le pool ou le supprimer.Reuse the context for another operation, put it back in the pool, or discard it.

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 d’application et les références d’e/s asynchrones.The lifetime of the new asynchronous socket operation context object is determined by references by the application code and asynchronous I/O references. L’application n’a pas besoin de conserver de référence à un objet de contexte de l’opération de socket asynchrone une fois qu’elle a été transmise comme paramètre à l’une des méthodes de l’opération de socket asynchrone.It is not necessary for the application to retain a reference to an asynchronous socket operation context object after it is submitted as a parameter to one of the asynchronous socket operation methods. La référence est conservée jusqu’au retour du rappel d’achèvement.It will remain referenced until the completion callback returns. Toutefois, il est avantageux pour l’application de conserver la référence au contexte afin de pouvoir la réutiliser pour une opération de socket asynchrone ultérieure.However it is advantageous for the application to retain the reference to the context so that it can be reused for a future asynchronous socket operation.

Constructeurs

SocketAsyncEventArgs()

Crée une instance SocketAsyncEventArgs vide.Creates an empty SocketAsyncEventArgs instance.

SocketAsyncEventArgs(Boolean)

Initialise la SocketAsyncEventArgs.Initializes the SocketAsyncEventArgs.

Propriétés

AcceptSocket

Obtient ou définit le socket à utiliser ou le socket créé pour accepter une connexion avec une méthode de socket asynchrone.Gets or sets the socket to use or the socket created for accepting a connection with an asynchronous socket method.

Buffer

Obtient la mémoire tampon des données à utiliser avec une méthode de socket asynchrone.Gets the data buffer to use with an asynchronous socket method.

BufferList

Obtient ou définit un tableau de la mémoire tampon de données à utiliser avec une méthode de socket asynchrone.Gets or sets an array of data buffers to use with an asynchronous socket method.

BytesTransferred

Obtient le nombre d'octets transférés dans l'opération de socket.Gets the number of bytes transferred in the socket operation.

ConnectByNameError

Obtient l'exception dans le cas d'un échec de connexion lorsqu'un DnsEndPoint a été utilisé.Gets the exception in the case of a connection failure when a DnsEndPoint was used.

ConnectSocket

Objet Socket créé et connecté après l'exécution correcte de la méthode ConnectAsync.The created and connected Socket object after successful completion of the ConnectAsync method.

Count

Obtient la quantité maximale de données, en octets, à envoyer ou recevoir dans une opération asynchrone.Gets the maximum amount of data, in bytes, to send or receive in an asynchronous operation.

DisconnectReuseSocket

Obtient ou définit une valeur qui indique si le socket peut être réutilisé après une opération de déconnexion.Gets or sets a value that specifies if socket can be reused after a disconnect operation.

LastOperation

Obtient le type d'opération de socket exécuté le plus récemment avec cet objet de contexte.Gets the type of socket operation most recently performed with this context object.

MemoryBuffer

Obtient la zone de mémoire à utiliser comme mémoire tampon avec une méthode de socket asynchrone.Gets the region of memory to use as a buffer with an asynchronous socket method.

Offset

Obtient l'offset, en octets, dans la mémoire tampon de données référencée par la propriété Buffer.Gets the offset, in bytes, into the data buffer referenced by the Buffer property.

ReceiveMessageFromPacketInfo

Obtient l'adresse IP et l'interface d'un paquet reçu.Gets the IP address and interface of a received packet.

RemoteEndPoint

Obtient ou définit le point de terminaison IP distant d'une opération asynchrone.Gets or sets the remote IP endpoint for an asynchronous operation.

SendPacketsElements

Obtient ou définit un tableau de mémoires tampons à envoyer pour une opération asynchrone utilisée par la méthode SendPacketsAsync(SocketAsyncEventArgs).Gets or sets an array of buffers to be sent for an asynchronous operation used by the SendPacketsAsync(SocketAsyncEventArgs) method.

SendPacketsFlags

Obtient ou définit une combinaison d'opérations de bits des valeurs TransmitFileOptions pour une opération asynchrone utilisée par la méthode SendPacketsAsync(SocketAsyncEventArgs).Gets or sets a bitwise combination of TransmitFileOptions values for an asynchronous operation used by the SendPacketsAsync(SocketAsyncEventArgs) method.

SendPacketsSendSize

Obtient ou définit la taille, en octets, du bloc de données utilisé dans l'opération d'envoi.Gets or sets the size, in bytes, of the data block used in the send operation.

SocketClientAccessPolicyProtocol
Obsolète.

Obtient ou définit le protocole à utiliser pour télécharger le fichier de stratégie d'accès au client de socket.Gets or sets the protocol to use to download the socket client access policy file.

SocketError

Obtient ou définit le résultat de l'opération de socket asynchrone.Gets or sets the result of the asynchronous socket operation.

SocketFlags

Obtient le résultat d'une opération de socket asynchrone ou définit le comportement d'une opération asynchrone.Gets the results of an asynchronous socket operation or sets the behavior of an asynchronous operation.

UserToken

Obtient ou définit un objet utilisateur ou application associé à cette opération de socket asynchrone.Gets or sets a user or application object associated with this asynchronous socket operation.

Méthodes

Dispose()

Libère les ressources non managées utilisées par l'instance SocketAsyncEventArgs et supprime éventuellement les ressources managées.Releases the unmanaged resources used by the SocketAsyncEventArgs instance and optionally disposes of the managed resources.

Equals(Object)

Détermine si l'objet spécifié est égal à l'objet actuel.Determines whether the specified object is equal to the current object.

(Hérité de Object)
Finalize()

Libère les ressources utilisées par la classe SocketAsyncEventArgs.Frees resources used by the SocketAsyncEventArgs class.

GetHashCode()

Sert de fonction de hachage par défaut.Serves as the default hash function.

(Hérité de Object)
GetType()

Obtient le Type de l'instance actuelle.Gets the Type of the current instance.

(Hérité de Object)
MemberwiseClone()

Crée une copie superficielle du Object actuel.Creates a shallow copy of the current Object.

(Hérité de Object)
OnCompleted(SocketAsyncEventArgs)

Représente une méthode qui est appelée lorsqu'une opération asynchrone se termine.Represents a method that is called when an asynchronous operation completes.

SetBuffer(Byte[], Int32, Int32)

Définit la mémoire tampon de données à utiliser avec une méthode de socket asynchrone.Sets the data buffer to use with an asynchronous socket method.

SetBuffer(Int32, Int32)

Définit la mémoire tampon de données à utiliser avec une méthode de socket asynchrone.Sets the data buffer to use with an asynchronous socket method.

SetBuffer(Memory<Byte>)

Définit la zone de mémoire à utiliser comme mémoire tampon avec une méthode de socket asynchrone.Sets the region of memory to use as a buffer with an asynchronous socket method.

ToString()

Retourne une chaîne qui représente l'objet actuel.Returns a string that represents the current object.

(Hérité de Object)

Événements

Completed

Événement utilisé pour terminer une opération asynchrone.The event used to complete an asynchronous operation.

S’applique à

Voir aussi