SocketAsyncEventArgs Sınıf
Tanım
Önemli
Bazı bilgiler ürünün ön sürümüyle ilgilidir ve sürüm öncesinde önemli değişiklikler yapılmış olabilir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.
Zaman uyumsuz yuva işlemini temsil eder.
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
- Devralma
- Uygulamalar
Örnekler
Aşağıdaki kod örneği, sınıfını kullanan SocketAsyncEventArgs yuva sunucusu için bağlantı mantığını uygular. Bağlantı kabul edildikten sonra istemciden okunan tüm veriler istemciye geri gönderilir. İstemci bağlantısı kesilene kadar okuma ve istemci desenine geri yansıma devam eder. Bu örnek tarafından kullanılan BufferManager sınıfı, yönteminin kod örneğinde SetBuffer(Byte[], Int32, Int32) görüntülenir. Bu örnekte kullanılan SocketAsyncEventArgsPool sınıfı oluşturucunun kod örneğinde SocketAsyncEventArgs görüntülenir.
// 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);
}
}
Açıklamalar
SocketAsyncEventArgs sınıfı, özelleştirilmiş yüksek performanslı yuva uygulamaları tarafından kullanılabilecek alternatif bir zaman uyumsuz desen sağlayan sınıf geliştirmeleri System.Net.Sockets.Socket kümesinin parçasıdır. Bu sınıf, yüksek performans gerektiren ağ sunucusu uygulamaları için özel olarak tasarlanmıştır. Bir uygulama, gelişmiş zaman uyumsuz deseni yalnızca veya yalnızca hedeflenen etkin alanlarda (örneğin, büyük miktarda veri alırken) kullanabilir.
Bu geliştirmelerin temel özelliği, yüksek hacimli zaman uyumsuz yuva G/Ç'leri sırasında nesnelerin tekrar tekrar ayrılmasının ve eşitlenmesinin engellenmesidir. Sınıfı tarafından System.Net.Sockets.Socket şu anda uygulanan Begin/End tasarım deseni, her zaman uyumsuz yuva işlemi için bir System.IAsyncResult nesnenin ayrılmasını gerektirir.
Yeni System.Net.Sockets.Socket sınıf geliştirmelerinde, zaman uyumsuz yuva işlemleri uygulama tarafından ayrılan ve bakımı yapılan yeniden kullanılabilir SocketAsyncEventArgs nesneler tarafından açıklanır. Yüksek performanslı yuva uygulamaları, sürdürülmesi gereken çakışan yuva işlemlerinin miktarını en iyi şekilde bilir. Uygulama, ihtiyaç duyduğu sayıda SocketAsyncEventArgs nesne oluşturabilir. Örneğin, bir sunucu uygulamasının gelen istemci bağlantı oranlarını desteklemek için her zaman bekleyen 15 yuva kabul işlemine sahip olması gerekiyorsa, bu amaç için 15 yeniden kullanılabilir SocketAsyncEventArgs nesne ayırabilir.
Bu sınıfla zaman uyumsuz yuva işlemi gerçekleştirme deseni aşağıdaki adımlardan oluşur:
Yeni SocketAsyncEventArgs bir bağlam nesnesi ayırın veya uygulama havuzundan ücretsiz bir nesne alın.
Bağlam nesnesinde özellikleri gerçekleştirilmek üzere olan işleme ayarlayın (tamamlanma geri çağırma yöntemi, veri arabelleği, arabelleğe uzaklık ve aktarılacak en fazla veri miktarı gibi).
Zaman uyumsuz işlemi başlatmak için uygun yuva yöntemini (xxxAsync) çağırın.
Zaman uyumsuz yuva yöntemi (xxxAsync) true döndürürse, geri çağırmada tamamlanma durumu için bağlam özelliklerini sorgula.
Zaman uyumsuz yuva yöntemi (xxxAsync) false döndürürse, işlem zaman uyumlu olarak tamamlanır. İşlem sonucu için bağlam özellikleri sorgulanabilir.
Bağlamı başka bir işlem için yeniden kullanın, havuza geri yerleştirin veya atın.
Yeni zaman uyumsuz yuva işlemi bağlam nesnesinin ömrü, uygulama kodu ve zaman uyumsuz G/Ç başvuruları tarafından yapılan başvurularla belirlenir. Zaman uyumsuz yuva işlem yöntemlerinden birine parametre olarak gönderildikten sonra uygulamanın zaman uyumsuz yuva işlemi bağlam nesnesine başvuruyu koruması gerekmez. Tamamlama geri çağırması dönene kadar başvurulu olarak kalır. Ancak, uygulamanın bağlam başvurusunu koruması avantajlıdır, böylece gelecekteki bir zaman uyumsuz yuva işlemi için yeniden kullanılabilir.
Oluşturucular
SocketAsyncEventArgs() |
Boş SocketAsyncEventArgs bir örnek oluşturur. |
SocketAsyncEventArgs(Boolean) |
SocketAsyncEventArgsöğesini başlatır. |
Özellikler
AcceptSocket |
Kullanılacak yuvayı veya zaman uyumsuz bir yuva yöntemiyle bağlantı kabul etmek için oluşturulan yuvayı alır veya ayarlar. |
Buffer |
Zaman uyumsuz yuva yöntemiyle kullanılacak veri arabelleği alır. |
BufferList |
Zaman uyumsuz yuva yöntemiyle kullanılacak bir veri arabelleği dizisini alır veya ayarlar. |
BytesTransferred |
Yuva işleminde aktarılan bayt sayısını alır. |
ConnectByNameError |
kullanıldığında bağlantı hatası DnsEndPoint durumunda özel durumu alır. |
ConnectSocket |
Yöntemi başarıyla tamamlandıktan ConnectAsync sonra oluşturulan ve bağlı Socket nesne. |
Count |
Zaman uyumsuz bir işlemde gönderilecek veya alınacak maksimum veri miktarını bayt cinsinden alır. |
DisconnectReuseSocket |
Bir bağlantı kesme işleminden sonra yuvanın yeniden kullanılıp kullanılamayabileceğini belirten bir değer alır veya ayarlar. |
LastOperation |
Bu bağlam nesnesiyle en son gerçekleştirilen yuva işleminin türünü alır. |
MemoryBuffer |
Zaman uyumsuz yuva yöntemiyle arabellek olarak kullanılacak bellek bölgesini alır. |
Offset |
Özelliği tarafından Buffer başvuruda bulunan veri arabelleğine bayt cinsinden uzaklığı alır. |
ReceiveMessageFromPacketInfo |
Alınan paketin IP adresini ve arabirimini alır. |
RemoteEndPoint |
Zaman uyumsuz bir işlem için uzak IP uç noktasını alır veya ayarlar. |
SendPacketsElements |
yöntemi tarafından kullanılan zaman uyumsuz bir işlem için gönderilecek arabellek dizisini SendPacketsAsync(SocketAsyncEventArgs) alır veya ayarlar. |
SendPacketsFlags |
yöntemi tarafından kullanılan zaman uyumsuz bir işlem için değerlerin bit düzeyinde bir bileşimini TransmitFileOptionsSendPacketsAsync(SocketAsyncEventArgs) alır veya ayarlar. |
SendPacketsSendSize |
Gönderme işleminde kullanılan veri bloğunun boyutunu bayt cinsinden alır veya ayarlar. |
SocketClientAccessPolicyProtocol |
Geçersiz.
Yuva istemcisi erişim ilkesi dosyasını indirmek için kullanılacak protokolü alır veya ayarlar. |
SocketError |
Zaman uyumsuz yuva işleminin sonucunu alır veya ayarlar. |
SocketFlags |
Zaman uyumsuz yuva işleminin sonuçlarını alır veya zaman uyumsuz bir işlemin davranışını ayarlar. |
UserToken |
Bu zaman uyumsuz yuva işlemiyle ilişkili bir kullanıcı veya uygulama nesnesini alır veya ayarlar. |
Yöntemler
Dispose() |
Örnek tarafından SocketAsyncEventArgs kullanılan yönetilmeyen kaynakları serbest bırakır ve isteğe bağlı olarak yönetilen kaynakları atılır. |
Equals(Object) |
Belirtilen nesnenin geçerli nesneye eşit olup olmadığını belirler. (Devralındığı yer: Object) |
Finalize() |
Sınıfı tarafından SocketAsyncEventArgs kullanılan kaynakları serbesttir. |
GetHashCode() |
Varsayılan karma işlevi işlevi görür. (Devralındığı yer: Object) |
GetType() |
Type Geçerli örneğini alır. (Devralındığı yer: Object) |
MemberwiseClone() |
Geçerli Objectöğesinin sığ bir kopyasını oluşturur. (Devralındığı yer: Object) |
OnCompleted(SocketAsyncEventArgs) |
Zaman uyumsuz bir işlem tamamlandığında çağrılan bir yöntemi temsil eder. |
SetBuffer(Byte[], Int32, Int32) |
Zaman uyumsuz yuva yöntemiyle kullanılacak veri arabelleği ayarlar. |
SetBuffer(Int32, Int32) |
Zaman uyumsuz yuva yöntemiyle kullanılacak veri arabelleği ayarlar. |
SetBuffer(Memory<Byte>) |
Zaman uyumsuz yuva yöntemiyle arabellek olarak kullanılacak bellek bölgesini ayarlar. |
ToString() |
Geçerli nesneyi temsil eden dizeyi döndürür. (Devralındığı yer: Object) |
Ekinlikler
Completed |
Zaman uyumsuz bir işlemi tamamlamak için kullanılan olay. |
Şunlara uygulanır
Ayrıca bkz.
- IAsyncResult
- Socket
- AcceptAsync(SocketAsyncEventArgs)
- ConnectAsync(SocketAsyncEventArgs)
- DisconnectAsync(SocketAsyncEventArgs)
- ReceiveAsync(SocketAsyncEventArgs)
- ReceiveFromAsync(SocketAsyncEventArgs)
- ReceiveMessageFromAsync(SocketAsyncEventArgs)
- SendAsync(SocketAsyncEventArgs)
- SendPacketsAsync(SocketAsyncEventArgs)
- SendToAsync(SocketAsyncEventArgs)
- .NET Framework'te Ağ Programlaması
- .NET Framework'te Ağ İzleme
- Sürüm 3.5’teki Yuva Performansı Geliştirmeleri