SocketAsyncEventArgs 클래스

정의

비동기 소켓 작업을 나타냅니다.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
상속
SocketAsyncEventArgs
구현

예제

다음 코드 예제에서는 SocketAsyncEventArgs 클래스를 사용 하는 소켓 서버에 대 한 연결 논리를 구현 합니다.The following code example implements the connection logic for the socket server that uses the SocketAsyncEventArgs class. 연결을 수락 하면 클라이언트에서 읽은 모든 데이터가 클라이언트로 다시 전송 됩니다.After accepting a connection, all data read from the client is sent back to the client. 클라이언트의 연결을 끊을 때까지 클라이언트 패턴에 대 한 읽기 및 echo가 계속 됩니다.The read and echo back to the client pattern is continued until the client disconnects. 이 예제에서 사용 하는 BufferManager 클래스는 SetBuffer(Byte[], Int32, Int32) 메서드에 대 한 코드 예제에 표시 됩니다.The BufferManager class that is used by this example is displayed in the code example for the SetBuffer(Byte[], Int32, Int32) method. 이 예제에서 사용 되는 SocketAsyncEventArgsPool 클래스는 SocketAsyncEventArgs 생성자의 코드 예제에 표시 됩니다.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);
    }

}    

설명

합니다 SocketAsyncEventArgs 향상 된 기능 집합의 일부인 클래스는 System.Net.Sockets.Socket 특수화 된 고성능 소켓 애플리케이션에서 사용할 수 있는 대체 비동기 패턴을 제공 하는 클래스입니다.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. 이 클래스는 높은 성능이 필요한 네트워크 서버 애플리케이션에 대 한 설계 되었습니다.This class was specifically designed for network server applications that require high performance. 애플리케이션 향상 된 비동기 패턴을 단독으로 사용할 수 또는 대상 핫 영역 (예: 많은 양의 데이터를 수신 하는 경우).An application can use the enhanced asynchronous pattern exclusively or only in targeted hot areas (for example, when receiving large amounts of data).

이러한 개선 사항의 주요 기능은 대량 비동기 소켓 I/O 중 개체의 반복 할당 및 동기화를 방지할 수 있습니다.The main feature of these enhancements is the avoidance of the repeated allocation and synchronization of objects during high-volume asynchronous socket I/O. 현재 System.Net.Sockets.Socket 클래스에서 구현 하는 Begin/End 디자인 패턴을 사용 하려면 각 비동기 소켓 작업에 대해 System.IAsyncResult 개체를 할당 해야 합니다.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.

System.Net.Sockets.Socket 클래스 개선 사항에서 비동기 소켓 작업에서 다시 사용할 수 있는 설명 SocketAsyncEventArgs 개체 할당 및 애플리케이션에서 유지 관리 합니다.In the new System.Net.Sockets.Socket class enhancements, asynchronous socket operations are described by reusable SocketAsyncEventArgs objects allocated and maintained by the application. 고성능 소켓 애플리케이션은 유지해야 하는 겹쳐진 소켓 작업량을 가장 잘 알고 있습니다.High-performance socket applications know best the amount of overlapped socket operations that must be sustained. 애플리케이션은 SocketAsyncEventArgs 개체를 필요한 개수만큼 만들 수 있습니다.The application can create as many of the SocketAsyncEventArgs objects that it needs. 예를 들어 서버 애플리케이션을 15 개의 소켓 들어오는 클라이언트 연결 속도 지원 하기 위해 항상 완료 되지 않은 작업을 허용 해야 하는 경우 다시 사용할 수 있는 15 할당할 수 있습니다 SocketAsyncEventArgs 해당 용도 대 한 개체입니다.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.

이 클래스를 사용하여 비동기 소켓 작업을 수행하기 위한 패턴은 다음 단계로 구성됩니다.The pattern for performing an asynchronous socket operation with this class consists of the following steps:

  1. SocketAsyncEventArgs 컨텍스트 개체를 할당하거나 애플리케이션 풀에서 무료 개체를 가져옵니다.Allocate a new SocketAsyncEventArgs context object, or get a free one from an application pool.

  2. 컨텍스트 개체의 속성을 수행 하려는 작업 (예: 완료 콜백 메서드, 데이터 버퍼, 버퍼에 대 한 오프셋 및 전송할 데이터의 최대 양)으로 설정 합니다.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. 적절한 소켓 메서드(xxxAsync)를 호출하여 비동기 작업을 시작합니다.Call the appropriate socket method (xxxAsync) to initiate the asynchronous operation.

  4. 비동기 소켓 메서드 (xxxAsync)가 true를 반환 하는 경우 콜백에서 컨텍스트 속성을 쿼리하여 완료 상태를 쿼리 합니다.If the asynchronous socket method (xxxAsync) returns true, in the callback, query the context properties for completion status.

  5. 비동기 소켓 메서드 (xxxAsync)가 false를 반환 하는 경우 작업이 동기적으로 완료 됩니다.If the asynchronous socket method (xxxAsync) returns false, the operation completed synchronously. 컨텍스트 속성에서 작업 결과를 쿼리할 수 있습니다.The context properties may be queried for the operation result.

  6. 컨텍스트를 다른 작업에 다시 사용하거나, 풀에 다시 넣거나, 삭제합니다.Reuse the context for another operation, put it back in the pool, or discard it.

새 비동기 소켓 작업 컨텍스트 개체의 수명은 애플리케이션 코드와 비동기 I/O 참조에서 참조 하 여 결정 됩니다.The lifetime of the new asynchronous socket operation context object is determined by references by the application code and asynchronous I/O references. 비동기 소켓 작업 방법 중 하나에 매개 변수로 제출된 후 애플리케이션이 비동기 소켓 작업 컨텍스트 개체에 대한 참조를 유지할 필요는 없습니다.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. 완료 콜백이 반환될 때까지 참조된 상태로 유지됩니다.It will remain referenced until the completion callback returns. 그러나 이후 비동기 소켓 작업에 대 한 다시 사용할 수 있도록 컨텍스트에 대 한 참조를 유지 하도록 애플리케이션에 대 한 것이 유용 합니다.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.

생성자

SocketAsyncEventArgs()

SocketAsyncEventArgs 인스턴스를 만듭니다.Creates an empty SocketAsyncEventArgs instance.

속성

AcceptSocket

비동기 소켓 메서드를 통해 연결을 허용하기 위해 만들었거나 사용할 소켓을 가져오거나 설정합니다.Gets or sets the socket to use or the socket created for accepting a connection with an asynchronous socket method.

Buffer

비동기 소켓 메서드에 사용할 데이터 버퍼를 가져옵니다.Gets the data buffer to use with an asynchronous socket method.

BufferList

비동기 소켓 메서드에 사용할 데이터 버퍼의 배열을 가져오거나 설정합니다.Gets or sets an array of data buffers to use with an asynchronous socket method.

BytesTransferred

소켓 작업에서 전송된 바이트 수를 가져옵니다.Gets the number of bytes transferred in the socket operation.

ConnectByNameError

DnsEndPoint를 사용할 때 연결 실패가 발생하는 경우의 예외를 가져옵니다.Gets the exception in the case of a connection failure when a DnsEndPoint was used.

ConnectSocket

Socket 메서드가 성공적으로 완료된 후 만들어지고 연결되는 ConnectAsync 개체입니다.The created and connected Socket object after successful completion of the ConnectAsync method.

Count

비동기 작업을 통해 보내거나 받을 최대 데이터 양(바이트)을 가져옵니다.Gets the maximum amount of data, in bytes, to send or receive in an asynchronous operation.

DisconnectReuseSocket

연결 끊기 작업이 완료된 후 소켓을 다시 사용할 수 있는지 여부를 지정하는 값을 가져오거나 설정합니다.Gets or sets a value that specifies if socket can be reused after a disconnect operation.

LastOperation

이 컨텍스트 개체를 사용하여 가장 최근에 수행한 소켓 작업의 유형을 가져옵니다.Gets the type of socket operation most recently performed with this context object.

MemoryBuffer

비동기 소켓 메서드를 사용하여 버퍼로 사용할 메모리 영역을 가져옵니다.Gets the region of memory to use as a buffer with an asynchronous socket method.

Offset

Buffer 속성에서 참조하는 데이터 버퍼의 오프셋(바이트)을 가져옵니다.Gets the offset, in bytes, into the data buffer referenced by the Buffer property.

ReceiveMessageFromPacketInfo

받은 패킷의 IP 주소 및 인터페이스를 가져옵니다.Gets the IP address and interface of a received packet.

RemoteEndPoint

비동기 작업의 원격 IP 엔드포인트를 가져오거나 설정합니다.Gets or sets the remote IP endpoint for an asynchronous operation.

SendPacketsElements

SendPacketsAsync(SocketAsyncEventArgs) 메서드로 비동기 작업을 수행할 때 보낼 버퍼의 배열을 가져오거나 설정합니다.Gets or sets an array of buffers to be sent for an asynchronous operation used by the SendPacketsAsync(SocketAsyncEventArgs) method.

SendPacketsFlags

TransmitFileOptions 메서드로 비동기 작업을 수행할 때 사용하는 SendPacketsAsync(SocketAsyncEventArgs) 값의 비트 조합을 가져오거나 설정합니다.Gets or sets a bitwise combination of TransmitFileOptions values for an asynchronous operation used by the SendPacketsAsync(SocketAsyncEventArgs) method.

SendPacketsSendSize

보내기 작업에 사용되는 데이터 블록의 크기(바이트)를 가져오거나 설정합니다.Gets or sets the size, in bytes, of the data block used in the send operation.

SocketClientAccessPolicyProtocol

소켓 클라이언트 액세스 정책 파일을 다운로드하는 데 사용할 프로토콜을 가져오거나 설정합니다.Gets or sets the protocol to use to download the socket client access policy file.

SocketError

비동기 소켓 작업의 결과를 가져오거나 설정합니다.Gets or sets the result of the asynchronous socket operation.

SocketFlags

비동기 소켓 작업의 결과를 가져오거나 비동기 작업의 동작을 설정합니다.Gets the results of an asynchronous socket operation or sets the behavior of an asynchronous operation.

UserToken

이 비동기 소켓 작업과 연결된 사용자 또는 애플리케이션 개체를 가져오거나 설정합니다.Gets or sets a user or application object associated with this asynchronous socket operation.

메서드

Dispose()

SocketAsyncEventArgs 인스턴스에서 사용하는 관리되지 않는 리소스를 해제하고, 관리되는 리소스를 선택적으로 삭제합니다.Releases the unmanaged resources used by the SocketAsyncEventArgs instance and optionally disposes of the managed resources.

Equals(Object)

지정한 개체와 현재 개체가 같은지 여부를 확인합니다.Determines whether the specified object is equal to the current object.

(다음에서 상속됨 Object)
Finalize()

SocketAsyncEventArgs 클래스에서 사용한 리소스를 해제합니다.Frees resources used by the SocketAsyncEventArgs class.

GetHashCode()

기본 해시 함수로 작동합니다.Serves as the default hash function.

(다음에서 상속됨 Object)
GetType()

현재 인스턴스의 Type을 가져옵니다.Gets the Type of the current instance.

(다음에서 상속됨 Object)
MemberwiseClone()

현재 Object의 단순 복사본을 만듭니다.Creates a shallow copy of the current Object.

(다음에서 상속됨 Object)
OnCompleted(SocketAsyncEventArgs)

비동기 작업이 완료되면 호출할 메서드를 나타냅니다.Represents a method that is called when an asynchronous operation completes.

SetBuffer(Byte[], Int32, Int32)

비동기 소켓 메서드에 사용할 데이터 버퍼를 설정합니다.Sets the data buffer to use with an asynchronous socket method.

SetBuffer(Int32, Int32)

비동기 소켓 메서드에 사용할 데이터 버퍼를 설정합니다.Sets the data buffer to use with an asynchronous socket method.

SetBuffer(Memory<Byte>)

비동기 소켓 메서드를 사용하여 버퍼로 사용할 메모리 영역을 설정합니다.Sets the region of memory to use as a buffer with an asynchronous socket method.

ToString()

현재 개체를 나타내는 문자열을 반환합니다.Returns a string that represents the current object.

(다음에서 상속됨 Object)

이벤트

Completed

비동기 작업을 완료하는 데 사용할 이벤트입니다.The event used to complete an asynchronous operation.

적용 대상

추가 정보