SocketAsyncEventArgs Kelas
Definisi
Penting
Beberapa informasi terkait produk prarilis yang dapat diubah secara signifikan sebelum dirilis. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Mewakili operasi soket asinkron.
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
- Warisan
- Penerapan
Contoh
Contoh kode berikut mengimplementasikan logika koneksi untuk server soket yang menggunakan SocketAsyncEventArgs kelas . Setelah menerima koneksi, semua data yang dibaca dari klien dikirim kembali ke klien. Baca dan gema kembali ke pola klien dilanjutkan sampai klien terputus. Kelas BufferManager yang digunakan oleh contoh ini ditampilkan dalam contoh kode untuk SetBuffer(Byte[], Int32, Int32) metode . Kelas SocketAsyncEventArgsPool yang digunakan dalam contoh ini ditampilkan dalam contoh kode untuk SocketAsyncEventArgs konstruktor.
// 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);
}
}
Keterangan
Kelas SocketAsyncEventArgs ini adalah bagian dari serangkaian peningkatan ke System.Net.Sockets.Socket kelas yang menyediakan pola asinkron alternatif yang dapat digunakan oleh aplikasi soket berkinerja tinggi khusus. Kelas ini dirancang khusus untuk aplikasi server jaringan yang membutuhkan performa tinggi. Aplikasi dapat menggunakan pola asinkron yang ditingkatkan secara eksklusif atau hanya di area panas yang ditargetkan (misalnya, saat menerima data dalam jumlah besar).
Fitur utama dari peningkatan ini adalah menghindari alokasi berulang dan sinkronisasi objek selama I/O soket asinkron volume tinggi. Pola desain Mulai/Akhir yang saat ini diterapkan oleh System.Net.Sockets.Socket kelas mengharuskan System.IAsyncResult objek dialokasikan untuk setiap operasi soket asinkron.
Dalam peningkatan kelas baru System.Net.Sockets.Socket , operasi soket asinkron dijelaskan oleh objek yang dapat SocketAsyncEventArgs digunakan kembali yang dialokasikan dan dikelola oleh aplikasi. Aplikasi soket berkinerja tinggi mengetahui dengan baik jumlah operasi soket yang tumpang tindih yang harus dipertahankan. Aplikasi dapat membuat sebanyak mungkin objek SocketAsyncEventArgs yang dibutuhkan. Misalnya, jika aplikasi server harus memiliki 15 operasi penerimaan soket yang luar biasa setiap saat untuk mendukung tingkat koneksi klien yang masuk, aplikasi dapat mengalokasikan 15 objek yang dapat digunakan SocketAsyncEventArgs kembali untuk tujuan tersebut.
Pola untuk melakukan operasi soket asinkron dengan kelas ini terdiri dari langkah-langkah berikut:
Alokasikan objek konteks SocketAsyncEventArgs baru, atau dapatkan yang gratis dari kumpulan aplikasi.
Atur properti pada objek konteks ke operasi yang akan dilakukan (metode panggilan balik penyelesaian, buffer data, offset ke dalam buffer, dan jumlah maksimum data yang akan ditransfer, misalnya).
Panggil metode soket yang sesuai (xxxAsync) untuk memulai operasi asinkron.
Jika metode soket asinkron (xxxAsync) mengembalikan true, dalam panggilan balik, kueri properti konteks untuk status penyelesaian.
Jika metode soket asinkron (xxxAsync) mengembalikan false, operasi selesai secara sinkron. Properti konteks mungkin ditanyakan untuk hasil operasi.
Gunakan kembali konteks untuk operasi lain, masukkan kembali ke dalam kumpulan, atau buang.
Masa pakai objek konteks operasi soket asinkron baru ditentukan oleh referensi oleh kode aplikasi dan referensi I/O asinkron. Aplikasi tidak perlu menyimpan referensi ke objek konteks operasi soket asinkron setelah dikirimkan sebagai parameter ke salah satu metode operasi soket asinkron. Objek tersebut akan tetap direferensikan sampai panggilan balik penyelesaian kembali. Namun, menguntungkan bagi aplikasi untuk mempertahankan referensi ke konteks sehingga dapat digunakan kembali untuk operasi soket asinkron di masa depan.
Konstruktor
SocketAsyncEventArgs() |
Membuat instans kosong SocketAsyncEventArgs . |
SocketAsyncEventArgs(Boolean) |
Menginisialisasi SocketAsyncEventArgs. |
Properti
AcceptSocket |
Mendapatkan atau mengatur soket yang akan digunakan atau soket yang dibuat untuk menerima koneksi dengan metode soket asinkron. |
Buffer |
Mendapatkan buffer data untuk digunakan dengan metode soket asinkron. |
BufferList |
Mendapatkan atau mengatur array buffer data untuk digunakan dengan metode soket asinkron. |
BytesTransferred |
Mendapatkan jumlah byte yang ditransfer dalam operasi soket. |
ConnectByNameError |
Mendapatkan pengecualian dalam kasus kegagalan koneksi saat DnsEndPoint digunakan. |
ConnectSocket |
Objek yang dibuat dan tersambung Socket setelah berhasil menyelesaikan ConnectAsync metode. |
Count |
Mendapatkan jumlah maksimum data, dalam byte, untuk dikirim atau diterima dalam operasi asinkron. |
DisconnectReuseSocket |
Mendapatkan atau menetapkan nilai yang menentukan apakah soket dapat digunakan kembali setelah operasi pemutusan sambungan. |
LastOperation |
Mendapatkan jenis operasi soket yang terakhir dilakukan dengan objek konteks ini. |
MemoryBuffer |
Mendapatkan wilayah memori untuk digunakan sebagai buffer dengan metode soket asinkron. |
Offset |
Mendapatkan offset, dalam byte, ke dalam buffer data yang dirujuk Buffer oleh properti . |
ReceiveMessageFromPacketInfo |
Mendapatkan alamat IP dan antarmuka paket yang diterima. |
RemoteEndPoint |
Mendapatkan atau mengatur titik akhir IP jarak jauh untuk operasi asinkron. |
SendPacketsElements |
Mendapatkan atau mengatur array buffer yang akan dikirim untuk operasi asinkron yang digunakan oleh SendPacketsAsync(SocketAsyncEventArgs) metode . |
SendPacketsFlags |
Mendapatkan atau mengatur kombinasi TransmitFileOptions nilai bitwise untuk operasi asinkron yang digunakan oleh SendPacketsAsync(SocketAsyncEventArgs) metode . |
SendPacketsSendSize |
Mendapatkan atau mengatur ukuran, dalam byte, dari blok data yang digunakan dalam operasi pengiriman. |
SocketClientAccessPolicyProtocol |
Kedaluwarsa.
Mendapatkan atau mengatur protokol yang akan digunakan untuk mengunduh file kebijakan akses klien soket. |
SocketError |
Mendapatkan atau mengatur hasil operasi soket asinkron. |
SocketFlags |
Mendapatkan hasil operasi soket asinkron atau mengatur perilaku operasi asinkron. |
UserToken |
Mendapatkan atau mengatur objek pengguna atau aplikasi yang terkait dengan operasi soket asinkron ini. |
Metode
Dispose() |
Merilis sumber daya tidak terkelola yang digunakan oleh SocketAsyncEventArgs instans dan secara opsional membuang sumber daya terkelola. |
Equals(Object) |
Menentukan apakah objek yang ditentukan sama dengan objek saat ini. (Diperoleh dari Object) |
Finalize() |
Membebaskan sumber daya yang digunakan oleh SocketAsyncEventArgs kelas . |
GetHashCode() |
Berfungsi sebagai fungsi hash default. (Diperoleh dari Object) |
GetType() |
Mendapatkan instans Type saat ini. (Diperoleh dari Object) |
MemberwiseClone() |
Membuat salinan dangkal dari yang saat ini Object. (Diperoleh dari Object) |
OnCompleted(SocketAsyncEventArgs) |
Mewakili metode yang dipanggil ketika operasi asinkron selesai. |
SetBuffer(Byte[], Int32, Int32) |
Mengatur buffer data yang akan digunakan dengan metode soket asinkron. |
SetBuffer(Int32, Int32) |
Mengatur buffer data yang akan digunakan dengan metode soket asinkron. |
SetBuffer(Memory<Byte>) |
Mengatur wilayah memori yang akan digunakan sebagai buffer dengan metode soket asinkron. |
ToString() |
Mengembalikan string yang mewakili objek saat ini. (Diperoleh dari Object) |
Acara
Completed |
Peristiwa yang digunakan untuk menyelesaikan operasi asinkron. |
Berlaku untuk
Lihat juga
- IAsyncResult
- Socket
- AcceptAsync(SocketAsyncEventArgs)
- ConnectAsync(SocketAsyncEventArgs)
- DisconnectAsync(SocketAsyncEventArgs)
- ReceiveAsync(SocketAsyncEventArgs)
- ReceiveFromAsync(SocketAsyncEventArgs)
- ReceiveMessageFromAsync(SocketAsyncEventArgs)
- SendAsync(SocketAsyncEventArgs)
- SendPacketsAsync(SocketAsyncEventArgs)
- SendToAsync(SocketAsyncEventArgs)
- Pemrograman Jaringan di .NET Framework
- Pelacakan Jaringan di .NET Framework
- Peningkatan Performa Soket di Versi 3.5