यूडीपी गैर-अवरोधक या प्राप्त करने के लिए एक अलग धागा?


10

मैं एक मल्टीप्लेयर गेम बना रहा हूं (64 खिलाड़ियों के लिए)। मैंने पहले से ही नेटवर्क लूप के लिए एक अलग थ्रेड रखने का फैसला किया था, लेकिन मैं सोच रहा था कि क्या यूडीपी प्राप्त करने के लिए एक अतिरिक्त धागा बनाना बेहतर होगा या प्राप्त सॉकेट को गैर-अवरोधक (अतिरिक्त थ्रेड के बिना) सेट करना होगा।

या असिंक्रोनस सॉकेट्स की तरह दूसरी विधि का उपयोग करना बेहतर है? बेहतर तरीके हमेशा स्वागत है!

जवाबों:


6

ठीक है, सबसे पहले, अगर आपके पास कुछ है और यह काम कर रहा है, तो आमतौर पर इसे इस तरह छोड़ने का एक अच्छा विचार है। जो ठीक नहीं है उसे क्यों तोड़ा जाए?

लेकिन अगर आपको परेशानी हो रही है, और वास्तव में अपने नेटवर्किंग कोड को फिर से लिखना चाहते हैं, तो मुझे लगता है कि आपके पास चार मुख्य विकल्प हैं:

  1. मल्टीथ्रेड ब्लॉकिंग कोड (अभी आप क्या कर रहे हैं)
  2. स्तर-ट्रिगर अधिसूचना के साथ गैर-अवरुद्ध सॉकेट्स
  3. तत्परता परिवर्तन अधिसूचना के साथ गैर-अवरुद्ध सॉकेट्स
  4. अतुल्यकालिक कुर्सियां

बहुत सारे मल्टीप्लेयर (सहकर्मी से सहकर्मी से लेकर बड़े पैमाने पर मल्टीप्लेयर) क्लाइंट और सर्वर पर लिखे जाने के बाद, मुझे लगता है कि विकल्प 2 कम से कम जटिलता की ओर जाता है, जो बहुत अच्छे प्रदर्शन के साथ, सर्वर और क्लाइंट गेम दोनों के लिए है। एक करीबी दूसरे के रूप में, मैं विकल्प 4 के साथ जाऊंगा, लेकिन आमतौर पर आपको अपने पूरे कार्यक्रम पर पुनर्विचार करने की आवश्यकता होती है, और मुझे ज्यादातर यह सर्वरों के लिए उपयोगी लगता है और ग्राहकों के लिए नहीं।

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

लेकिन इन सबसे ऊपर, अधिकांश सॉकेट कार्यान्वयन (और उस पर अधिकांश I / O कार्यान्वयन) न्यूनतम स्तर पर गैर-अवरुद्ध हैं। तुच्छ कार्यक्रमों के विकास को सरल बनाने के लिए ब्लॉकिंग ऑपरेशन बस प्रदान किए जाते हैं। जब एक सॉकेट ब्लॉक हो रहा है, तो उस धागे में सीपीयू पूरी तरह से निष्क्रिय है, इसलिए पहले से ही गैर-अवरुद्ध कार्य पर अवरुद्ध अमूर्त पर एक गैर-अवरुद्ध अमूर्त का निर्माण क्यों करें?

यदि आपने इसे आज़माया नहीं है तो नॉन-ब्लॉकिंग सॉकेट प्रोग्रामिंग थोड़ी कठिन है, लेकिन यह पता चला है कि यह काफी सरल है, और यदि आप पहले से ही इनपुट मतदान कर रहे हैं, तो आपके पास पहले से ही गैर-अवरुद्ध सॉकेट्स करने का मन है।

पहली चीज जो आप करना चाहते हैं वह सॉकेट को गैर-अवरुद्ध करने के लिए सेट करना है। आप उसके साथ करते हैं fcntl()

उसके बाद, इससे पहले कि आप कर send(), recv(), sendto(), recvfrom(), accept()( connect()या अन्य कॉल कि धागा ब्लॉक सकता है, तो आप फोन पर कुछ भिन्न है) select()सॉकेट पर। select()आपको बताता है कि बाद में पढ़ने या लिखने के संचालन को अवरुद्ध किए बिना सॉकेट पर किया जा सकता है या नहीं। अगर ऐसा है, तो आप अपने इच्छित ऑपरेशन को सुरक्षित रूप से कर सकते हैं, और सॉकेट ब्लॉक नहीं होगा।

एक खेल में यह शामिल करना काफी सरल है। यदि आपके पास पहले से गेम लूप है, उदाहरण के लिए:

while game_is_running do
    poll_input()
    update_world()
    do_sounds()
    draw_world()
end

आप इसे इस तरह से बदल सकते हैं:

while game_is_running do
    poll_input()
    read_network()
    update_world()
    do_sounds()
    write_network()
    draw_world()
end

कहाँ पे

function read_network()
    while select(socket, READ) do
        game.net_input.enqueue(recv(socket))
    end
end

तथा

function write_network()
    while not game.net_output.empty and select(socket, WRITE) do
        send(socket, game.net_output.dequeue())
    end
end

संसाधनों के संदर्भ में, एकमात्र पुस्तक जो मुझे लगता है कि हर कोई अपने बुकशेल्व में होना चाहिए, भले ही वह एकमात्र पुस्तक हो, जो कि " यूनिक्स नेटवर्क प्रोग्रामिंग, वॉल्यूम 1. " दिवंगत रिचर्ड स्टीवंस द्वारा की गई हो। इससे कोई फर्क नहीं पड़ता कि आप विंडोज या अन्य ओएस या भाषा सॉकेट प्रोग्रामिंग करते हैं। जब तक आप इस पुस्तक को नहीं पढ़ते, तब तक आप सॉकेट्स को नहीं समझते।

एक और संसाधन जहां कई सॉकेट प्रोग्रामिंग के संदर्भ में उपलब्ध समाधान का एक सामान्य अवलोकन (ज्यादातर सर्वर प्रोग्रामिंग के लिए प्रासंगिक) मिल सकती है इस पेज


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

3
@YickickLange: नहीं, लेकिन मैं आपको गेम-विशिष्ट पुस्तकों की तलाश करने की सलाह नहीं दूंगा, क्योंकि नेटवर्किंग बहुत शैली-अज्ञेयवादी है, और साथ ही कोई अन्य पुस्तक स्टीवंस की पुस्तक के स्तर तक नहीं है। यूडीपी का उपयोग करने के लिए यश, हालांकि, संदेश-उन्मुख कार्यक्रमों का उपयोग करते समय एक संदेश-उन्मुख प्रोटोकॉल का उपयोग करना एक अच्छा विचार है (जैसे अधिकांश गेम)। कई लोग टीसीपी पर एक संदेश अमूर्त लिखना समाप्त करते हैं, जो कि एक संदेश-उन्मुख प्रोटोकॉल (आईपी) पर निर्मित एक धारा-उन्मुख अमूर्तता है।
पांडा पायजामा

-1

आपने यह नहीं लिखा कि आप किस प्रोग्रामिंग-लैंग्वेज का उपयोग कर रहे हैं, लेकिन अधिकांश भाषाएँ अच्छी एसिंक्रोनस सॉकेट फ्रेमवर्क प्रदान करती हैं जो अक्सर अंतर्निहित ऑपरेटिंग सिस्टम की सुविधाओं का उपयोग करती हैं।

जब आप ब्लॉकिंग सॉकेट्स के आधार पर अपना स्वयं का थ्रेडेड कार्यान्वयन लिखते हैं (याद रखें: जब आपके पास कई क्लाइंट होते हैं, तो आपको हर एक सॉकेट के लिए एक थ्रेड की आवश्यकता होती है), आप बस यह पुनर्निमित करने जा रहे हैं कि एसिंक्रोनस सॉकेट फ्रेमवर्क पहले से ही क्या प्रदान करता है।

इसलिए मैं आपको अतुल्यकालिक सॉकेट्स का उपयोग करने की सलाह दूंगा।


4
उसे हर एक सॉकेट के लिए एक धागे की आवश्यकता क्यों है? विशेष रूप से एसिंक्स सॉकेट्स के साथ? कई हैवीवेट सर्वर सॉकेट डेटा को संसाधित करने के लिए एक "थ्रेड पूल" मॉडल का उपयोग करते हैं, जहां प्रत्येक थ्रेड सेवाएं एन क्लाइंट होती हैं और उन्हें जरूरत के अनुसार मार दिया जाता है या मार दिया जाता है। जरा सोचिए इस जवाब में सुधार की जरूरत है: D
ग्रिम्सहॉव

@Grimshaw मुझे लगता है कि आपने मेरे जवाब को गलत समझा। मुझे लगता है कि मैंने अब स्पष्ट कर दिया है कि ब्लॉकिंग सॉकेट्स का उपयोग करते समय एक बहु-थ्रेडेड मॉडल की आवश्यकता होगी।
फिलिप

@Philipp मैंने यह नहीं बताया कि मैं किस प्रोग्रामिंग भाषा का उपयोग करता हूं क्योंकि, मुझे लगा कि यह वास्तव में प्रश्न के लिए प्रासंगिक नहीं था (मैं वैसे भी c ++ का उपयोग करता हूं)। अतुल्यकालिक सॉकेट का उपयोग करने के लिए आपकी सिफारिश के लिए मैं आपको धन्यवाद देता हूं। क्या आप खेल (इंजन) में इन प्रकार के तरीकों को सीखने के लिए एक अनुशंसित पुस्तक / वेबपेज जानते हैं?
यानिक लैंग

@ ग्रीमशॉ: और प्रत्येक थ्रेड सेवा Nक्लाइंट कैसे करता है? यदि आप अवरुद्ध कर रहे हैं, और आप यह सुनिश्चित करना चाहते हैं कि प्रत्येक सॉकेट को शेष सॉकेट्स की स्थिति की परवाह किए बिना अपना डेटा संसाधित किया जाए, तो आपके पास प्रति सॉकेट में एक धागा होना चाहिए। कि, या अवरुद्ध सॉकेट का उपयोग न करें।
पांडा पजामा

मेरी टिप्पणी आपके उत्तर के पहले संस्करण में थी, इस बीच, आपने इसे संपादित किया और ठीक किया, जो मैंने कहा उसे भूल
जाइए
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.