2012-09-22 6 views
6

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

मैं प्राप्त करने के लिए बाइट्स की सटीक संख्या को प्राप्त करने (पढ़ने) अंत में बफर कैसे सेट कर सकता हूं? क्या यह जानने का कोई तरीका है कि भेजने (लेखन) पक्ष पर डेटा कितना बड़ा है?

मैंने PeekNamedPipe को देखा है, लेकिन यह कार्य बाइट टाइप किए गए नामित पाइप के लिए बेकार दिखाई देता है?

lpBytesLeftThisMessage [बाहर, वैकल्पिक] एक चर कि इस संदेश में शेष बाइट्स की संख्या प्राप्त करने के लिए एक सूचक। यह पैरामीटर बाइट-टाइप नामित पाइप या अज्ञात पाइप के लिए शून्य होगा। यदि कोई डेटा पढ़ा नहीं जाता है तो यह पैरामीटर न्यूल हो सकता है।

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365779(v=vs.85).aspx

एक ऐसी स्थिति के लिए सबसे अच्छा कैसे निपटता है अगर आपको सटीक आवश्यक बफर आकार निर्धारित नहीं कर सकता?

भेजा जा रहा है कोड

string strData; 
strData = "ShortLittleString"; 

DWORD numBytesWritten = 0; 
result = WriteFile(
    pipe, // handle to our outbound pipe 
    strData.c_str(), // data to send 
    strData.length(), // length of data to send (bytes) 
    &numBytesWritten, // will store actual amount of data sent 
    NULL // not using overlapped IO 
); 

पढ़ना कोड:

DWORD numBytesToRead0 = 0; 
DWORD numBytesToRead1 = 0; 
DWORD numBytesToRead2 = 0; 

BOOL result = PeekNamedPipe(
pipe, 
NULL, 
42, 
&numBytesToRead0, 
&numBytesToRead1, 
&numBytesToRead2 
); 

char * buffer ; 

buffer = new char[numBytesToRead2]; 

char data[1024]; //1024 is way too big and numBytesToRead2 is always 0 
DWORD _numBytesRead = 0; 

BOOL result = ReadFile(
pipe, 
data, // the data from the pipe will be put here 
1024, // number of bytes allocated 
&_numBytesRead, // this will store number of bytes actually read 
NULL // not using overlapped IO 
); 

बफर उपरोक्त कोड में PeakNamedPipe समारोह के रूप में आकार 0 की हमेशा होता है सब numBytesToRead चर के लिए 0 देता है। क्या इस बफर आकार को बिल्कुल सेट करने का कोई तरीका है? यदि नहीं, ऐसी स्थिति को संभालने का सबसे अच्छा तरीका क्या है? किसी भी मदद के लिए धन्यवाद!

+0

एक साधारण दृष्टिकोण पहली डेटा लंबाई लिखने के लिए है, तो है। रिसीवर तो पहले लंबाई को सरल पढ़ सकता है और बफर आवंटित कर सकता है। पाइप संदेश मोड के तरीके के विपरीत नहीं है। –

उत्तर

1

ठीक है, आप ReadFile() का उपयोग कर रहे हैं। प्रलेखन कहते हैं, अन्य बातों के अलावा:

एक नामित पाइप संदेश मोड में पढ़ा जा रहा है और अगले संदेश अब nNumberOfBytesToRead पैरामीटर निर्दिष्ट करता है की तुलना में है, ReadFile FALSE देता है और GetLastError रिटर्न ERROR_MORE_DATA। संदेश के शेष को को रीडफाइल या PeekNamedPipefunction के बाद के कॉल द्वारा पढ़ा जा सकता है।

क्या आपने कोशिश की? मैंने कभी इस तरह एक पाइप का उपयोग नहीं किया है :-), केवल उन्हें बाल प्रक्रिया के stdin/आउट हैंडल तक पहुंचने के लिए उपयोग किया जाता है।

मुझे लगता है कि उपरोक्त को जितनी बार आवश्यक हो उतनी बार दोहराया जा सकता है, "संदेश का शेष" कुछ हद तक गलत वर्णन: मुझे लगता है कि अगर "शेष" आपके बफर में फिट नहीं होता है तो आप बस एक और ERROR_MORE_DATA प्राप्त करें ताकि आप शेष शेष को प्राप्त कर सकें।

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

+0

नहीं, मैंने नहीं किया है। यह एक हैक की तरह लगता है, लेकिन क्या आप सुझाव दे रहे हैं कि मैं बहुत छोटी वृद्धि और लूप में पढ़ता हूं जब तक कि मुझे अब कोई ERROR_MORE_DATA त्रुटि नहीं मिलती है? :) यह काम करना चाहिए, लेकिन मैं संदेश में डेटा आकार को जोड़ने या धारावाहिक डेटा में अप्रासंगिक डेटा के साथ समाप्त होने से बचने की कोशिश कर रहा हूं - मूल रूप से संदेश पढ़ने के बाद किसी भी char/string आधारित सफाई कार्य। क्या EOF तक टेक्स्ट फ़ाइल पढ़ने की तरह पढ़ने का कोई तरीका नहीं है? क्या मैं लिखने की तरफ अपना खुद का ईओएफ डाल सकता हूं? – Rudolf

+0

मैं संदेश मोड का उपयोग नहीं कर रहा हूं, मैं बाइट मोड का उपयोग कर रहा हूं। :) लेकिन मुझे लगता है कि आपने मुझे एक विचार दिया है, मुझे लगता है कि निश्चित लंबाई वर्ण भेजते समय बाइट मोड का उपयोग किया जाना है, मैं सिस्टम को एक संदेश मोड पाइप में काट दूंगा और बदल दूंगा? – Rudolf

+0

बाइट मोड विशेष रूप से आपके द्वारा लागू किए जा रहे उपयोग के मामले के लिए मैसेजिंग प्रोटोकॉल, या इसकी कमी के प्रबंधन के लिए * आप * पर ऑनस डालने के लिए डिज़ाइन किया गया है। दूसरे शब्दों में, संदेश-पाइप का हिस्सा संदेश की लंबाई का गुण है। बाइट-मोड में ऐसी कोई विशेषता मौजूद नहीं है जब तक कि * आप इसे प्रबंधित करने वाले डेटा को भेजकर प्रबंधित न करें। इसे एक और तरीका दें, संदेश मोड एक लड़का है जो आपको एक बॉक्स सौंपता है जिस पर यह लेबल है कि यह कितना है। बाइट मोड सिर्फ एक आदमी है जो आपको उत्पाद फेंक रहा है। जब तक कि आप 'लड़के' के दिमाग में क्या नहीं जानते हैं, आपके पास वास्तव में काम करने के लिए पर्याप्त नहीं है। – WhozCraig

3

आपको लगता है कि आप डेटा आकार भेजने के लिए lpTotalBytesAvail का उपयोग क्यों नहीं कर सकते?यह हमेशा बाइट्स मोड में मेरे लिए काम करता है। यदि यह हमेशा शून्य है तो संभवतः आपने कुछ गलत किया है। डेटा बफर के रूप में std::vector का उपयोग करने का भी सुझाव दें, कच्चे पॉइंटर्स और new कथन के साथ गड़बड़ करने से यह काफी सुरक्षित है।

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

नमूना कोड:

// Get data size available from pipe 
DWORD bytesAvail = 0; 
BOOL isOK = PeekNamedPipe(hPipe, NULL, 0, NULL, &bytesAvail, NULL); 
if(!isOK) 
{ 
    // Check GetLastError() code 
} 

// Allocate buffer and peek data from pipe 
DWORD bytesRead = 0;  
std::vector<char> buffer(bytesAvail); 
isOK = PeekNamedPipe(hPipe, &buffer[0], bytesAvail, &bytesRead, NULL, NULL); 
if(!isOK) 
{ 
    // Check GetLastError() code 
} 
+0

lpTotalBytesAvail मेरे लिए बहुत अच्छा काम किया! हंस पासेंट ने सुझाव दिया था कि इसने आकार को पूर्ववत करने के लिए मुझे बहुत सारी परेशानी और महंगी बफर प्रतियां बचाईं। –

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