तो यहां एक उत्तर है जो आपको शुरू कर देगा - जो मेरे blog post से अधिक शुरुआती स्तर है।
नेट में एक एसिंक पैटर्न है जो एक प्रारंभ * और अंत * कॉल के आसपास घूमता है। उदाहरण के लिए - BeginReceive
और EndReceive
। वे लगभग हमेशा अपने गैर-एसिंक समकक्ष होते हैं (इस मामले में Receive
); और सटीक एक ही लक्ष्य प्राप्त करें।
याद रखने की सबसे महत्वपूर्ण बात यह है कि सॉकेट लोग केवल कॉल एसिंक बनाने से अधिक करते हैं - वे आईओसीपी (आईओ प्राप्ति बंदरगाह, लिनक्स/मोनो के पास इन दो हैं लेकिन मैं नाम भूल जाता हूं) का खुलासा करता हूं जो अत्यंत महत्वपूर्ण है सर्वर पर उपयोग करने के लिए; आईओसीपी क्या करता है इसका क्रूक्स यह है कि डेटा के लिए इंतजार करते समय आपका एप्लिकेशन थ्रेड का उपभोग नहीं करता है।
कैसे शुरू/अंत पैटर्न
उपयोग करने के लिए हर शुरू * यह गैर async समकक्ष है करने के लिए विधि comparisson में ठीक 2 अधिक बहस करना होगा।पहला एक AsyncCallback है, दूसरा एक वस्तु है। इन दोनों का मतलब क्या है, "जब आप काम करते हैं तो कॉल करने का एक तरीका यहां है" और "यहां कुछ डेटा है जो मुझे उस विधि के अंदर चाहिए।" जिस पद्धति को हमेशा बुलाया जाता है, वही हस्ताक्षर होता है, इस विधि के अंदर आप अंत * समकक्ष को कॉल करते हैं ताकि यह परिणाम प्राप्त हो सके कि आपने यह सिंक्रनाइज़ किया है। उदाहरण के लिए:
private void BeginReceiveBuffer()
{
_socket.BeginReceive(buffer, 0, buffer.Length, BufferEndReceive, buffer);
}
private void EndReceiveBuffer(IAsyncResult state)
{
var buffer = (byte[])state.AsyncState; // This is the last parameter.
var length = _socket.EndReceive(state); // This is the return value of the method call.
DataReceived(buffer, 0, length); // Do something with the data.
}
यहाँ क्या होता है नेट सॉकेट से डेटा के लिए इंतज़ार कर, जैसे ही यह डेटा यह EndReceiveBuffer
कॉल करता है और इसे करने के लिए 'कस्टम डेटा' से होकर गुजरता है (इस मामले buffer
में) हो जाता है शुरू होता है है state.AsyncResult
के माध्यम से। जब आप EndReceive
पर कॉल करते हैं तो यह आपको प्राप्त होने वाले डेटा की लंबाई वापस देगा (या कुछ विफल होने पर अपवाद फेंक देगा)। सॉकेट के लिए
बेहतर पैटर्न
यह फ़ॉर्म आपको केंद्रीय त्रुटि हैंडलिंग दे देंगे - यह कहीं भी इस्तेमाल किया जा सकता है, जहां async पैटर्न एक धारा की तरह 'बात' (जैसे टीसीपी क्रम में आता है यह भेजा गया था लपेटता , इसलिए इसे Stream
ऑब्जेक्ट के रूप में देखा जा सकता है)।
private Socket _socket;
private ArraySegment<byte> _buffer;
public void StartReceive()
{
ReceiveAsyncLoop(null);
}
// Note that this method is not guaranteed (in fact
// unlikely) to remain on a single thread across
// async invocations.
private void ReceiveAsyncLoop(IAsyncResult result)
{
try
{
// This only gets called once - via StartReceive()
if (result != null)
{
int numberOfBytesRead = _socket.EndReceive(result);
if(numberOfBytesRead == 0)
{
OnDisconnected(null); // 'null' being the exception. The client disconnected normally in this case.
return;
}
var newSegment = new ArraySegment<byte>(_buffer.Array, _buffer.Offset, numberOfBytesRead);
// This method needs its own error handling. Don't let it throw exceptions unless you
// want to disconnect the client.
OnDataReceived(newSegment);
}
// Because of this method call, it's as though we are creating a 'while' loop.
// However this is called an async loop, but you can see it the same way.
_socket.BeginReceive(_buffer.Array, _buffer.Offset, _buffer.Count, SocketFlags.None, ReceiveAsyncLoop, null);
}
catch (Exception ex)
{
// Socket error handling here.
}
}
स्वीकारना एकाधिक कनेक्शन
क्या आप आम तौर पर कर एक वर्ग है कि आपके सॉकेट आदि (और साथ ही अपने async पाश) शामिल हैं लिख सकते हैं और प्रत्येक ग्राहक के लिए एक बनाने के लिए है। उदाहरण के लिए तो:
public class InboundConnection
{
private Socket _socket;
private ArraySegment<byte> _buffer;
public InboundConnection(Socket clientSocket)
{
_socket = clientSocket;
_buffer = new ArraySegment<byte>(new byte[4096], 0, 4096);
StartReceive(); // Start the read async loop.
}
private void StartReceive() ...
private void ReceiveAsyncLoop() ...
private void OnDataReceived() ...
}
प्रत्येक ग्राहक कनेक्शन अपने सर्वर वर्ग द्वारा पता लगाया जाना चाहिए (ताकि आप उन्हें सफाई से जब सर्वर बंद हो जाता है,/डिस्कनेक्ट कर सकते हैं और साथ ही खोज के रूप में उन्हें ढूंढ निकालेंगे)।
बेकार प्लग: http://jonathan.dickinsons.co.za/blog/2011/02/net-sockets-and-you/ - यह एसिंक लूप पर संक्षेप में छूता है; और इसमें एक वास्तविक कार्यान्वयन है (आपको 'थ्रेडपूल' का उपयोग नहीं करना चाहिए जैसे कि जमाल सुझाया गया है)। –