2010-11-25 12 views
6

निर्दिष्ट करने वाले बूस्ट एएसओओ का उपयोग करके एक आईस्ट्रीम बनाएं, मुझे एशियो लाइब्रेरी को बढ़ावा देने में कोई समस्या है। मैंने क्लाइंट और सर्वर के बीच सॉकेट बनाने की सफलतापूर्वक कोशिश की, इसमें सर्वर पर आईपी और पोर्ट निर्दिष्ट करने के लिए संकल्पकों का निर्माण शामिल है (सर्वर को केवल पोर्ट की आवश्यकता है) और अन्य ऑब्जेक्ट्स, लेकिन, सबसे महत्वपूर्ण बात यह है कि इसका उपयोग करना आवश्यक है write और read_some सॉकेट से/पढ़ने और लिखने के कार्यों के रूप में। मैं वास्तव में स्ट्रीम का उपयोग करने की सराहना करता हूं, और यह एएसओ को बढ़ावा देने में संभव है, लेकिन यह अजीब है ... स्ट्रीम बनाने के लगभग सभी उदाहरणों में, सर्वर बनाने के लिए पोर्ट प्रदान करना आवश्यक है, ठीक है, चलिए क्लाइंट के बारे में बात करते हैंआईपी और पोर्ट

tcp::iostream() s(argv[1], "daytime"); 

ठीक है, मैं वास्तव में समझ में नहीं आता वास्तव में क्या पहले पैरामीटर में पारित हो जाता है और: ... ग्राहक के पक्ष में, यह धारा से जोड़ने के लिए निर्देशांक निर्दिष्ट करने के लिए iostream निर्माता का उपयोग करने के लिए आवश्यक है, यहाँ कोड है पता नहीं क्या दिन कभी भी प्रतिनिधित्व कर सकता है ... असल में, मैं कह रहा हूं: "हे स्ट्रीम, आपको इस सर्वर से कनेक्ट होना चाहिए ..." लेकिन मैं उस सर्वर के आईपी और पोर्ट को कैसे निर्दिष्ट कर सकता हूं? ध्यान दें कि, विपरीत पर, सब कुछ लगभग स्पष्ट सर्वर साइड है:

boost::asio::io_service io_s; 
tcp::acceptor acc(io_s, tcp::endpoint(tcp::v4(), 1950)); 
for (;;) { 
    tcp::iostream stream; 
    acc.accept(*stream.rdbuf()); 
    stream << "Message" << std::endl; 
} 

इस मॉडल का उपयोग, मैं आदेश भेजने और प्राप्त करने में

stream << mymessage_to_send << std::endl; 
stream >> a_string_containing_my_message; 

उपयोग करना चाहते हैं। मैं यह कैसे कर सकता हूं? बहुत बहुत धन्यवाद।

उत्तर

1

मैंने Boost.Asio का उपयोग कर क्लाइंट/सर्वर सिस्टम लिखा है। स्रोत GitHub पर उपलब्ध है: Client.cpp और Server.cpp। Boost.Asio के साथ Boost.Serialization का उपयोग करके मुझे तार पर मनमानी डेटास्ट्रक्चर भेजने की अनुमति मिलती है। मुझे कहना होगा कि यह काफी प्रभावशाली है!

+0

ठीक है, इसे तुरंत जांच करने जा रहा ... धन्यवाद – Andry

+0

तुम कोशिश यदि आप चाहें तो मेरे कार्यान्वयन के बारे में मुझसे पूछने के लिए स्वतंत्र। सौभाग्य! –

+0

ठीक है, मैं आपके कोड को देखकर कुछ चीजों की कोशिश कर रहा हूं ... मैं आपके जैसा अनुभव नहीं कर रहा हूं ... अच्छा, प्रश्न आने वाले हैं, अब मैं बस कह सकता हूं: कमाल कोड !!!!! – Andry

17

बढ़ावा asio नमूना कोड आप उद्धृत किया:

tcp::iostream s(argv[1], "daytime"); 

सेवाओं तालिका में एक देखने (आमतौर पर/etc/एक Linux सिस्टम पर सेवाओं में) है, जो उस के लिए बंदरगाह की पहचान के रूप में "दिन" का उपयोग करता है दिन के समय सेवा 13.

है आप एक बंदरगाह है कि अच्छी तरह से ज्ञात सेवाओं में से एक नहीं है से कनेक्ट करना चाहते हैं, तो आप की तरह कुछ के साथ ऐसा कर सकते हैं:

tcp::iostream s("localhost", "57002"); 

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

सॉकेट क्लाइंट पक्ष आसपास iostream बनाना:

बेशक

, "स्थानीय होस्ट" एक आईपी पता "127.0.0.1"

+6

यह चयनित उत्तर होना चाहिए। – Collin

+1

इस तथ्य के अलावा कि iostream के बाद कोई() नहीं होना चाहिए अन्यथा आप एक फ़ंक्शन वापस कर रहे हैं? – CashCow

+0

@CashCow - lol! मैं बस ओपी से कॉपी किया, और स्पष्ट किया। लेकिन अच्छी पकड़! – Arunas

0

के सभी 3 मुद्दों यहाँ हल करते हैं के साथ प्रतिस्थापित किया जा सकता है।

यह वास्तव में सरल है:

boost::asio::ip::tcp::iostream socketStream; 
socketStream.connect(hostname, std::to_string(port)); 

आप धारा की स्थिति जांचने कि क्या यह सफलतापूर्वक जुड़ा हुआ देखना है।

सॉकेट सर्वर पक्ष के आसपास iostream बनाना।

मान लिया जाये कि आप अपने स्वीकर्ता वस्तु है और यह स्वाभाविक है और सुनने ..

boost::asio::ip::tcp::iostream connectionSocketStream; // from the connection object 
acceptor.accept(*connectionSocketStream.rdbuf()); 

// या

acceptor.async_accept(*connectionSocketStream.rdbuf(), callback); 

जहां कॉलबैक एक समारोह है कि एक त्रुटि कोड लेता है।

वस्तुओं स्ट्रीमिंग

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

जवाब इसलिए एक बढ़ावा संग्रह का उपयोग करने के लिए है, और आप जब तक एक पाठ या बाइनरी संग्रह का उपयोग कर सकते के रूप में आप एक ही दोनों सिरों का उपयोग करें। इससे कोई फर्क नहीं पड़ता कि एक तरफ 64-बिट बड़े-एंडियन का उपयोग कर रहा है और दूसरी तरफ 32-बिट थोड़ा एंडियन या कोई अन्य मिश्रण है।

द्विआधारी संग्रह का उपयोग करके आप संदेश इस तरह से भेजना होगा:

boost::archive::binary_oarchive oarch(socketStream, boost::archive::no_header); 
oarch << "Message"; 

धारा फ्लश करने के लिए याद रखें (socketStream, नहीं oarch) जब आप सभी आप इस बिंदु पर भेजना चाहते हैं भेजने के पूरा कर लिया है।

और संदेश

boost::archive::binary_iarchive iarch(socketStream, boost::archive::no_header); 
iarch >> message; 

प्राप्त आप संभवतः विशेष रूप से आउटबाउंड के लिए एक संग्रह बनाने और भर में इसका इस्तेमाल होता है,। यदि आप स्ट्रीमिंग त्रुटि प्राप्त करते हैं तो इनबाउंड के लिए आपको समस्याएं हो सकती हैं क्योंकि यह आपके संग्रह को तोड़ देगा।

आप एक द्विआधारी एक के बजाय एक पाठ संग्रह का उपयोग कर सकते हैं।

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

नोट: आदिम प्रकार, जैसे std :: स्ट्रिंग और यहां तक ​​कि वेक्टर < पूर्णांक> आदि स्वचालित रूप से एक संग्रह द्वारा नियंत्रित किया जाता है। अपने स्वयं के वर्गों को विशेष ओवरलोड की आवश्यकता होगी कि उन्हें कैसे स्ट्रीम किया जाए। आपको बढ़ावा :: संग्रह दस्तावेज पढ़ना चाहिए।

नोट: इससे पहले कि धारा खोल दिया गया है आप स्ट्रीम करने के लिए संग्रह वस्तु कनेक्ट कर सकते हैं। संग्रह streambuf ऑब्जेक्ट के आसपास काम करता है जो सफलतापूर्वक स्ट्रीम खोलने पर निर्भर नहीं होता है।

no_header बिना बनाना एक मुद्दा होगा, हालांकि के रूप में अभिलेखागार तुरंत निर्माण पर धारा का उपयोग करने के (पढ़ने के लिए या उनके हेडर लिखने के लिए)

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