2012-06-26 15 views
5

में पढ़ने के लिए एक सॉकेट से डेटा पढ़ने के लिए सी/सी ++ तरीका है और प्राप्तकर्ता बफर फ़ाइल (ऑफस्ट्रीम) या एक समान स्वयं-विस्तारित ऑब्जेक्ट है (वेक्टर उदाहरण)?सी ++ पढ़ा() - एक सॉकेट से एक ऑफस्ट्रीम

संपादित करें: प्रश्न उठता है, जबकि मैंने अनुमान लगाया कि स्ट्रीम सॉकेट को कैसे पढ़ा जाए, जो 10000+ बाइट फ़ाइल कहें। मैंने स्टैक्स पर 20000 या 50000 बाइट्स (अब के लिए काफी बड़ा) डालने की तरह कभी नहीं किया था, जहां एक फ़ाइल में चिपकने तक फ़ाइल को अस्थायी रूप से संग्रहीत किया जा सकता था। क्यों न सिर्फ इसे सीधे फ़ाइल में स्ट्रीम करने के लिए स्ट्रीम करें।

बहुत आप चार * एक एसटीडी के अंदर पर प्राप्त कर सकते हैं की तरह: स्ट्रिंग, मैं

read(int fd, outFile.front(), std::npos); // npos = INT_MAX 

या ऐसा ही कुछ की तरह कुछ के बारे में सोचा।

अंत संपादित

धन्यवाद।

+1

हां। काफी से कुछ लोगों ने स्ट्रीम बफर लिखा है जो सॉकेट से जुड़ते हैं। जबकि वे शुरू में कम से कम अच्छे लगते हैं, कम से कम मैंने जो देखा है, वे शायद ही कभी अभ्यास में अच्छी तरह से काम करते हैं। आपको (लगभग) को कुछ प्रकार के एसिंक्रोनस ऑपरेशन (उदा।, जैसे एएसआईओ करता है) को अच्छी तरह से काम करने के लिए जोड़ने की आवश्यकता है। http://socketstream.sourceforge.net/, http://www.pcs.cnu.edu/~dgame/sockets/socketsC++/sockets.html, आदि –

उत्तर

4

यह साधारण है, और अपनी उंगलियों के ऊपर से है, लेकिन मुझे लगता है कि इन पंक्तियों के साथ कुछ बाहर काम करेगा:

template <unsigned BUF_SIZE> 
struct Buffer { 
    char buf_[BUF_SIZE]; 
    int len_; 
    Buffer() : buf_(), len_(0) {} 
    int read (int fd) { 
     int r = read(fd, buf_ + len_, BUF_SIZE - len_); 
     if (r > 0) len_ += r; 
     return r; 
    } 
    int capacity() const { return BUF_SIZE - len_; } 
} 

template <unsigned BUF_SIZE> 
struct BufferStream { 
    typedef std::unique_ptr< Buffer<BUF_SIZE> > BufferPtr; 
    std::vector<BufferPtr> stream_; 
    BufferStream() : stream_(1, BufferPtr(new Buffer<BUF_SIZE>)) {} 
    int read (int fd) { 
     if ((*stream_.rbegin())->capacity() == 0) 
      stream_.push_back(BufferPtr(new Buffer<BUF_SIZE>)); 
     return (*stream_.rbegin())->read(fd); 
    } 
}; 

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

std::vector<char> input; 
char in; 
int r; 
while ((r = read(fd, &in, 1)) == 1) input.push_back(in); 

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

मुझे वास्तव में उस समाधान के बारे में उम्मीद नहीं है जिसे मैंने अपनाया था। मैं सिर्फ एक विस्तार से प्रदान करना चाहता था कि एक आत्म-विस्तारित वस्तु कैसे बनाएं जो काफी जगह और समय कुशल थी। अपने उद्देश्यों के आधार पर, आप इसे विस्तारित करना चाहते हैं, या अपना खुद का लिखना चाहते हैं। मेरे सिर के ऊपर से, कुछ सुधार हो सकता है:

  • उपयोग std::list बजाय, आकार बदलने
  • एपीआई कितने बाइट्स
  • उपयोग readv पढ़ने के लिए हमेशा कम से कम अनुमति देने के लिए निर्दिष्ट करने के लिए एक पैरामीटर के लिए अनुमति देते हैं वेक्टर से बचने के लिए BUF_SIZE बाइट्स (या BUF_SIZE बाइट्स से अधिक) एक समय में पढ़ने के लिए
+0

दिलचस्प। मैं वास्तव में एक बड़ा चार बफर घोषित करने का तरीका नहीं था। लेकिन संरचना बफर {char buf_ [BUF_SIZE] में; ... आप एक चार बफर घोषित कर रहे हैं। –

+1

@WesMiller: 'read' को एक बफर पास करने की आवश्यकता है, और आप एक स्वयं विस्तारित डेटा संरचना में एकत्रित डेटा चाहते थे, जिसका अर्थ है' रीड 'रिटर्न के बाद बफर को संग्रहीत करना। यदि आप वास्तव में उपयोगकर्ता स्पेस कोड में कोई बफर नहीं बनाया है, तो आप 0 कॉपी सेमेन्टिक्स (कर्नेल द्वारा उपयोग किए जाने वाले नेटवर्क बफर तक सीधे पहुंच) के साथ अपना स्वयं का नेटवर्क I/O डिवाइस ड्राइवर बनाना चाहते हैं। – jxh

+0

ठीक है, अब तक नहीं जा रहा है। मैंने उन मामलों के लिए स्वयं विस्तारित ऑब्जेक्ट पर विचार किया जिसमें प्राप्त डेटा स्ट्रीम (यह एक स्ट्रीम सॉकेट है) अज्ञात आकार का था। जैसा कि उपरोक्त मूल पोस्टिंग में संपादित किया गया है, मुझे अज्ञात आकार की एक फ़ाइल प्राप्त होगी और आशा है कि चार बफर [50000] "पर्याप्त पर्याप्त" होने की उम्मीद न करें। जल्द या बाद में होने की गारंटी नहीं है। –

0

boost::asio में स्ट्रीम समर्थन पर नज़र डालें।

+2

"तू बूस्ट नहीं करेगा" - प्रबंधन। –

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