c# - सी#में सॉकेट प्रोग्रामिंग के साथ शुरू करना-सर्वोत्तम प्रथाओं




.net sockets (2)

1 - एक सॉकेट पर बाध्यकारी और सुनना

मुझे ठीक लग रहा है। आपका कोड सॉकेट को केवल एक आईपी पते पर बांध देगा। यदि आप बस किसी भी आईपी पते / नेटवर्क इंटरफ़ेस को सुनना चाहते हैं, तो IPAddress.Any उपयोग करें। कोई भी:

serverSocket.Bind(new IPEndPoint(IPAddress.Any, 4444));

भविष्य के सबूत होने के लिए, आप आईपीवी 6 का समर्थन करना चाह सकते हैं। किसी भी आईपीवी 6 पते को सुनने के लिए, IPAddress.IPv6Any किसी भी IPAddress.IPv6Any के स्थान पर उपयोग करें। कोई भी।

ध्यान दें कि आप एक ही समय में किसी भी आईपीवी 4 और किसी भी आईपीवी 6 पते पर नहीं सुन सकते हैं, सिवाय इसके कि आप दोहरी-स्टैक सॉकेट का उपयोग करते हैं। यह आपको IPV6_V6ONLY सॉकेट विकल्प को अनसेट करने की आवश्यकता होगी:

serverSocket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)27, 0);

अपनी सॉकेट के साथ Teredo को सक्षम करने के लिए, आपको PROTECTION_LEVEL_UNRESTRICTED सॉकेट विकल्प सेट करने की आवश्यकता है:

serverSocket.SetSocketOption(SocketOptionLevel.IPv6, (SocketOptionName)23, 10);

2 - डेटा प्राप्त करना

मैं NetworkStream का उपयोग करने की अनुशंसा करता हूं जो मैन्युअल रूप से हिस्सों को पढ़ने के बजाय Stream में सॉकेट को लपेटता है।

बाइट्स की एक निश्चित संख्या को पढ़ना थोड़ा अजीब है हालांकि:

using (var stream = new NetworkStream(serverSocket)) {
   var buffer = new byte[MaxMessageLength];
   while (true) {
      int type = stream.ReadByte();
      if (type == BYE) break;
      int length = stream.ReadByte();
      int offset = 0;
      do
         offset += stream.Read(buffer, offset, length - offset);
      while (offset < length);
      ProcessMessage(type, buffer, 0, length);
   }
}

जहां NetworkStream वास्तव में चमकता है कि आप इसे किसी अन्य Stream तरह उपयोग कर सकते हैं। यदि सुरक्षा महत्वपूर्ण है, तो सर्वर को प्रमाणीकृत करने के लिए बस NetworkStream को NetworkStream में लपेटें और (वैकल्पिक रूप से) X.50 9 प्रमाणपत्र वाले क्लाइंट। संपीड़न वैसे ही काम करता है।

var sslStream = new SslStream(stream, false);
sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true);
// receive/send data SSL secured

3 - डेटा भेजना और डेटा लंबाई निर्दिष्ट करना

आपका दृष्टिकोण काम करना चाहिए, यद्यपि आप शायद पहिया को फिर से शुरू करने और इसके लिए एक नया प्रोटोकॉल तैयार करने के लिए सड़क पर नहीं जाना चाहेंगे। BEEP पर एक नज़र डालें या शायद protobuf तरह कुछ सरल भी देखें।

अपने लक्ष्यों के आधार पर, डब्ल्यूसीएफ या कुछ अन्य आरपीसी तंत्र जैसे सॉकेट के ऊपर एक अमूर्तता चुनने के बारे में सोचने लायक हो सकता है।

4/5/6 - समापन और अज्ञात डिस्कनेक्शन

क्या jerryjvl ने कहा :-) jerryjvl विश्वसनीय होने पर केवल विश्वसनीय पहचान तंत्र पिंग या रख-रखाव भेज रहे हैं।

जबकि आपको किसी भी मामले में अज्ञात डिस्कनेक्शन से निपटना होगा, मैं व्यक्तिगत रूप से बिना किसी चेतावनी के इसे बंद करने के बजाय पारस्परिक समझौते में कनेक्शन बंद करने के लिए कुछ प्रोटोकॉल तत्व रखूंगा।

मैंने सॉकेट के बारे में SO पर कई संसाधन देखे हैं। मेरा मानना ​​है कि उनमें से कोई भी उन विवरणों को कवर नहीं करता जिन्हें मैं जानना चाहता था। मेरे आवेदन में, सर्वर सभी प्रसंस्करण करता है और ग्राहकों को आवधिक अद्यतन भेजता है।

इस पोस्ट का इरादा सॉकेट एप्लिकेशन विकसित करते समय आवश्यक सर्वोत्तम बुनियादी विचारों को कवर करना और सर्वोत्तम प्रथाओं पर चर्चा करना है। यहां मूलभूत चीजें हैं जिन्हें आप लगभग सभी सॉकेट आधारित अनुप्रयोगों के साथ देखेंगे।

1 - एक सॉकेट पर बाध्यकारी और सुनना

मैं निम्नलिखित कोड का उपयोग कर रहा हूँ। यह मेरी मशीन पर अच्छी तरह से काम करता है। जब मैं इसे वास्तविक सर्वर पर तैनात करता हूं तो क्या मुझे किसी और चीज की देखभाल करने की ज़रूरत है?

IPHostEntry localHost = Dns.GetHostEntry(Dns.GetHostName());
IPEndPoint endPoint = new IPEndPoint(localHost.AddressList[0], 4444);

serverSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, 
                     ProtocolType.Tcp);
serverSocket.Bind(endPoint);
serverSocket.Listen(10);

2 - डेटा प्राप्त करना

मैंने 255 आकार के बाइट सरणी का उपयोग किया है। तो जब मुझे 255 बाइट्स से अधिक डेटा प्राप्त हो रहा है, तो मुझे पूरा डेटा प्राप्त होने तक प्राप्त विधि को कॉल करने की आवश्यकता है, है ना? एक बार मुझे पूरा डेटा मिलने के बाद, मुझे पूरा संदेश प्राप्त करने के लिए अब तक प्राप्त सभी बाइट्स को जोड़ना होगा। क्या वो सही है? या क्या एक बेहतर दृष्टिकोण है?

3 - डेटा भेजना और डेटा लंबाई निर्दिष्ट करना

चूंकि संदेश प्राप्त करने की लंबाई खोजने के लिए टीसीपी में कोई रास्ता नहीं है, इसलिए मैं संदेश में लंबाई जोड़ने की योजना बना रहा हूं। यह पैकेट का पहला बाइट होगा। इसलिए क्लाइंट सिस्टम जानता है कि पढ़ने के लिए कितना डेटा उपलब्ध है।

कोई अन्य बेहतर दृष्टिकोण?

4 - ग्राहक को बंद करना

जब ग्राहक बंद हो जाता है, तो यह बंदरगाह को इंगित करने वाले सर्वर को एक संदेश भेजेगा। सर्वर क्लाइंट विवरण को इसकी ग्राहक सूची से हटा देगा। सॉकेट को डिस्कनेक्ट करने के लिए क्लाइंट साइड पर इस्तेमाल किया गया कोड (मैसेजिंग भाग दिखाया नहीं गया है)।

client.Shutdown(SocketShutdown.Both);
client.Close();

कोई सुझाव या समस्याएं?

5 - सर्वर बंद करना

सर्वर बंद करने का संकेत देने वाले सभी ग्राहकों को संदेश भेजता है। जब यह संदेश प्राप्त होता है तो प्रत्येक क्लाइंट सॉकेट को डिस्कनेक्ट कर देगा। ग्राहक सर्वर पर बंद संदेश भेज देंगे और बंद कर देंगे। एक बार जब सर्वर सभी ग्राहकों से घनिष्ठ संदेश प्राप्त करता है, तो यह सॉकेट को डिस्कनेक्ट करता है और सुनना बंद कर देता है। संसाधनों को जारी करने के लिए प्रत्येक क्लाइंट सॉकेट पर कॉल का निपटान करें। क्या यह सही दृष्टिकोण है?

6 - अज्ञात क्लाइंट डिस्कनेक्शन

कभी-कभी, क्लाइंट सर्वर को सूचित किये बिना डिस्कनेक्ट हो सकता है। इसे संभालने की मेरी योजना यह है: जब सर्वर सभी ग्राहकों को संदेश भेजता है, तो सॉकेट स्थिति की जांच करें। यदि यह कनेक्ट नहीं है, तो उस क्लाइंट को क्लाइंट सूची से हटा दें और उस क्लाइंट के लिए सॉकेट बंद करें।

कोई भी मदद बहुत अच्छी रहेगी!








sockets