2011-02-08 19 views
15

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

उदाहरण के लिए कहें कि आपके पास नेटवर्क सर्वर है। यह प्रतिक्रियाओं के लिए बस इंतज़ार कर रहा है। एक पैकेट आता है और सर्वर को पैकेट को सत्यापित करने की आवश्यकता होती है और फिर इसे तय करने की आवश्यकता होती है कि इसे कैसे संभाला जाए।

फिलहाल मैं हेडर में पैकेट आईडी पर स्विच करके ऐसा कर रहा हूं और फिर प्रत्येक पैकेट प्रकार को संभालने वाले फ़ंक्शन कॉल का एक बड़ा समूह है। जटिल नेटवर्किंग सिस्टम के साथ यह एक मोनोलिथिक स्विच स्टेटमेंट में परिणाम देता है और मुझे वास्तव में इसे इस तरह से संभालना पसंद नहीं है। एक तरीका मैंने माना है कि हैंडलर कक्षाओं के मानचित्र का उपयोग करना है। मैं फिर पैकेट को प्रासंगिक वर्ग में पास कर सकता हूं और आने वाले डेटा को संभाल सकता हूं। मेरे साथ समस्या यह है कि मुझे नक्शा के साथ प्रत्येक पैकेट हैंडलर को "रजिस्टर" करने का कोई तरीका चाहिए। इसका मतलब है, आम तौर पर, मुझे कक्षा की एक स्थिर प्रतिलिपि बनाने की आवश्यकता होती है और फिर कन्स्ट्रक्टर में इसे केंद्रीय पैकेट हैंडलर के साथ पंजीकृत किया जाता है। हालांकि यह काम करता है यह वास्तव में इसे संभालने के एक सुरुचिपूर्ण और विचित्र तरीके की तरह लगता है।

संपादित करें: समान रूप से यह एक अच्छा सिस्टम होना आदर्श होगा जो दोनों तरीकों से काम करता है। यानी एक वर्ग संरचना जो आसानी से उसी पैकेट प्रकार को प्राप्त करने के रूप में उन्हें प्राप्त करती है (स्पष्ट रूप से विभिन्न कार्यों के माध्यम से)।

क्या कोई मुझे इनकमिंग पैकेट को संभालने के लिए बेहतर तरीके से इंगित कर सकता है? लिंक और उपयोगी जानकारी की बहुत सराहना की जाती है!

क्षमा करें अगर मैंने अपनी समस्या का वर्णन नहीं किया है, तो मुझे इसका वर्णन करने में असमर्थता भी है क्योंकि मैंने कभी भी समाधान के साथ आने में कामयाब नहीं किया है।

+0

आपको हैंडलर कक्षाओं की एक स्थिर प्रति की आवश्यकता नहीं है। आप निर्माता में उदाहरण पारित कर सकते हैं। हालांकि, कोई सुधार नहीं है। :( –

+0

@ मार्टिन्हो: लेकिन इसका मतलब है कि कहीं मुझे प्रत्येक संभावित वर्ग को तुरंत चालू करना होगा। जहां, कक्षा के लिए कार्यान्वयन फ़ाइल में, मैं स्वयं का एक स्थिर संस्करण घोषित करता हूं तो निर्माता को स्वचालित रूप से कॉल किया जाता है। – Goz

+0

क्या आपने http : //ieeexplore.ieee.org/xpl/freeabs_all.jsp? arnumber = 631153? –

उत्तर

5

पैकेट प्रकार को संभालने के तरीके के बारे में: मेरे लिए नक्शा सबसे अच्छा है। हालांकि मैं मानचित्र के बजाय एक सादा सरणी (या एक वेक्टर) का उपयोग करता हूं। यदि आप अपने पैकेट प्रकारों को अनुक्रमिक रूप से 0.

कक्षा संरचना के अनुसार क्रमशः एक्सेस समय निरंतर बना देंगे। ऐसे पुस्तकालय हैं जो पहले से ही यह काम करते हैं: Available Game network protocol definition languages and code generation। जैसे Google's Protocol Buffer आशाजनक प्रतीत होता है। यह प्रोटोकॉल विवरण में प्रत्येक संदेश के लिए गेटर्स, सेटर्स, क्रमबद्धता और deserialization दिनचर्या के साथ एक भंडारण वर्ग उत्पन्न करता है। प्रोटोकॉल विवरण भाषा कम या ज्यादा समृद्ध दिखती है।

1

हैंडलर उदाहरणों का एक मानचित्र इसे संभालने का सबसे अच्छा तरीका है। इसके बारे में कुछ भी सुरुचिपूर्ण नहीं है।

+1

लेकिन निश्चित रूप से खूनी ढंग से खूनी;) – Goz

+0

मैं अभी भी यह सोचने में मदद नहीं कर सकता कि इसे संभालने का एक बेहतर तरीका है, हालांकि ... – Goz

+1

निश्चित रूप से निश्चित मात्रा में है और इस मामले में यह सिर्फ एक प्रश्न है कि आप इसे कैसे और कहां फैलाते हैं। – Blrfl

1

मेरे अनुभव में, टेबल संचालित पार्सिंग सबसे प्रभावी विधि है।

हालांकि std::map अच्छा है, मैं स्थिर टेबल का उपयोग कर समाप्त होता हूं। std::map स्थिर तालिका के रूप में स्थैतिक रूप से प्रारंभ नहीं किया जा सकता है। इसे रन-टाइम के दौरान लोड किया जाना चाहिए। टेबल्स (संरचनाओं के सरणी) को डेटा के रूप में घोषित किया जा सकता है और संकलन समय पर प्रारंभ किया जा सकता है। मुझे पर्याप्त बड़ी संख्या में टेबल का सामना नहीं हुआ है जहां एक रैखिक खोज एक बाधा थी। आम तौर पर तालिका का आकार इतना छोटा होता है कि बाइनरी खोज में ओवरहेड एक रैखिक खोज से धीमा होता है।

उच्च प्रदर्शन के लिए, मैं संदेश डेटा को तालिका में एक अनुक्रमणिका के रूप में उपयोग करूंगा।

1

जब आप ओओपी कर रहे हैं, तो आप ऑब्जेक्ट के रूप में हर चीज का प्रतिनिधित्व करने की कोशिश करते हैं, है ना? तो आपके प्रोटोकॉल संदेश ऑब्जेक्ट भी बन जाते हैं; आपके पास शायद बेस क्लास YourProtocolMessageBase होगा जो किसी भी संदेश के व्यवहार को समाहित करेगा और जिसमें से आप अपने बहुरूप विशेष रूप से विशेष संदेश प्राप्त करेंगे। फिर आपको प्रत्येक संदेश को चालू करने के लिए एक तरीका चाहिए (यानी प्रत्येक YourProtocolMessageBase उदाहरण) बाइट्स की एक स्ट्रिंग में, और रिवर्स करने का एक तरीका। इस तरह के तरीकों को serialization तकनीकों कहा जाता है; कुछ मेटाप्रोग्रामिंग-आधारित implementations मौजूद हैं।

अजगर में

त्वरित उदाहरण:

from socket import * 
sock = socket(AF_INET6, SOCK_STREAM) 
sock.bind(("localhost", 1234)) 
rsock, addr = sock.accept() 

सर्वर ब्लॉक, एक ग्राहक के लिए एक और उदाहरण ऊपर आग:

from socket import * 
clientsock = socket(AF_INET6, SOCK_STREAM) 
clientsock.connect(("localhost", 1234)) 

अभी सेवा का उपयोग अजगर के अंतर्निहित क्रमांकन मॉड्यूल, pickle; ग्राहक:

import pickle 
obj = {1: "test", 2: 138, 3: ("foo", "bar")} 
clientsock.send(pickle.dumps(obj)) 

सर्वर:

>>> import pickle 
>>> r = pickle.loads(rsock.recv(1000)) 
>>> r 
{1: 'test', 2: 138, 3: ('foo', 'bar')} 

तो, जैसा कि आप देख सकते हैं, मैं सिर्फ लिंक स्थानीय एक अजगर वस्तु पर भेज दिया। क्या यह ओओपी नहीं है?

मुझे लगता है कि धारावाहिक करने का एकमात्र संभावित विकल्प बिमाप आईडी ⇔ कक्षाओं को बनाए रखना है। यह वास्तव में अपरिहार्य दिखता है।

1

आप एक ही पैकेट नेटवर्क प्रोटोकॉल का उपयोग करना जारी रखना चाहते हैं, लेकिन प्रोग्रामिंग में ऑब्जेक्ट में इसका अनुवाद करना चाहते हैं, है ना?

ऐसे कई प्रोटोकॉल हैं जो आपको प्रोग्रामिंग ऑब्जेक्ट्स के रूप में डेटा का इलाज करने की अनुमति देते हैं, लेकिन ऐसा लगता है कि आप प्रोटोकॉल को बदलना नहीं चाहते हैं, जिस तरह से यह आपके एप्लिकेशन में इलाज किया जाता है।

क्या पैकेट "टैग" या मेटाडेटा या किसी भी "आईडी" या "डेटा प्रकार" जैसी किसी चीज़ के साथ आते हैं जो आपको किसी विशिष्ट ऑब्जेक्ट क्लास पर मैप करने की अनुमति देता है? यदि ऐसा होता है, तो आप एक सरणी बना सकते हैं जो आईडी स्टोर करता है। और मिलान करने वाली कक्षा, और एक वस्तु उत्पन्न करते हैं।

+0

हां इसमें एक पैकेट आईडी है। मैं नहीं देख सकता कि आप कुछ प्रकार के अद्वितीय आईडी के बिना पैकेट प्रकारों की पहचान कैसे करेंगे ... – Goz

+0

यदि आप हमें पैकेट आईडी बना सकते हैं। "एक पैकेट वर्गीकृत करने के लिए" तो आप कुछ ऐसा कर सकते हैं: ऑब्जेक्ट फ़ंक्शन पैकेटटॉक्लास (स्ट्रिंग पैकेट टाइप टाइप) {...} एक फ़ंक्शन जो आईडी पर आधारित किसी दिए गए वर्ग का ऑब्जेक्ट उत्पन्न करता है, जिसे "फैक्ट्री" पैटर्न भी कहा जाता है, या के नरम – umlcat

1

इसे संभालने के लिए एक और ओओ तरीका राज्य पैटर्न का उपयोग कर एक राज्य मशीन बनाना है।

आने वाले कच्चे डेटा हैंडलिंग पार्स करने जाता है, जहां राज्य मशीनों एक सुरुचिपूर्ण समाधान प्रदान

आप कार्रवाई करने के लिए एक डेटा बफर है, प्रत्येक राज्य एक हैंडल बफर विधि है कि पार्स करता है और (आप सुरुचिपूर्ण और प्रदर्शन के बीच चयन करना होगा) बफर के अपने हिस्से को संसाधित करता है (यदि पहले से ही संभव है) और सामग्री के आधार पर अगला राज्य सेट करता है।

यदि आप प्रदर्शन के लिए जाना चाहते हैं, तो भी आप एक राज्य मशीन का उपयोग कर सकते हैं, लेकिन ओओ भाग छोड़ दें।

संबंधित मुद्दे