2011-02-02 7 views
6

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

pid_t pid = NULL; 
int pipefd[2]; 
FILE* output; 
char line[256]; 

pipe(pipefd); 
pid = fork(); 
if (pid == 0) 
{ 
// Child 
    close(pipefd[0]); 
    dup2(pipefd[1], STDOUT_FILENO); 
    dup2(pipefd[1], STDERR_FILENO); 
    execl("/sbin/wifiscan", "/sbin/wifiscan", (char*) NULL); 
} 

//Only parent gets here. Listen to what the wifi scan says 
close(pipefd[1]); 
output = fdopen(pipefd[0], "r"); 

while(fgets(line, sizeof(line), output)) 
{ 
//Here we can listen to what wifiscan sends to its standard output 
} 

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

लिनक्स में प्रक्रियाओं के बीच डेटा का विश्वसनीय रूप से विनिमय करने के अन्य साधन क्या हैं?

उत्तर

7

मुझे लगता है कि क्या हो रहा है कि fgets() NUL पात्रों को ठीक से पढ़ रही है, लेकिन आप लाइन है कि पढ़ा गया के अंत होने के रूप में पहले एक व्याख्या कर रहे हैं। यह मुश्किल है क्योंकि fgets() टेक्स्ट इनपुट के लिए है, और यह '\ 0' को एक सेंटीनेल के रूप में उपयोग करता है, जो वर्णों की संख्या को वापस नहीं लौटाता है। यहां तक ​​कि यदि आप जानते हैं कि प्रत्येक पंक्ति \n समाप्त हो जाएगी, तो ऐसी स्थिति है कि एक पंक्ति में एम्बेडेड कच्चे बाइनरी डेटा में \n भी शामिल होगा। तो, fread() पर स्विच करें, जो बाइनरी के लिए है। आप प्रत्येक संदेश के सामने एक निश्चित लंबाई (उदाहरण के लिए 2-बाइट, 4-बाइट) संदेश आकार डाल सकते हैं ताकि दूसरी तरफ पहले इसे पढ़ सकें, फिर सटीक संदेश आकार के लिए fread() करें, आंशिक संदेश पढ़ने के साथ गंदे मुद्दों से परहेज करें ।

आप वास्तव में यह पाठ और द्विआधारी के कुछ अजीब संकर रखना चाहते हैं, तो आप कितना धारा आप कर रहे हैं के साथ आगे पता लगाने के लिए fgets() के बाद ftell() का उपयोग कर की कोशिश कर सकते हैं, और इसलिए कितने वर्ण अपने बफर में होना चाहिए , लेकिन मैंने कभी गंभीर प्रणाली नहीं देखी है जो कुछ हैकी है।

रिकॉर्ड के लिए, बाइनरी डेटा में हर एक चरित्र हेक्स-एन्कोडिंग जैसे कुछ अक्षम किए बिना, आप केवल परेशानी वाले चरित्र को एन्कोड कर सकते हैं। उदाहरण के लिए, सी स्ट्रिंग शाब्दिक भागने के दृश्यों का उपयोग किया जा सकता है, \0 एक एनयूएल और \\ एक एकल \ का प्रतिनिधित्व करता है। यद्यपि दृष्टिहीन जांच करने में कम आसान है, लेकिन octal \NNN का उपयोग करके गैर-प्रिंट करने योग्य वर्णों को एन्कोड/डीकोड करने के लिए प्रोग्रामेटिक रूप से आसान हो सकता है। यदि बहुत सारे गैर-प्रिंट करने योग्य वर्ण हैं, तो बेस -64 यूयूनकोड दृष्टिकोण - जैसे कि एमआईएमई ईमेल संलग्नक में उपयोग किया जाता है - एक और उपयुक्त लेकिन पूरी तरह से गैर-पठनीय एन्कोडिंग है।

+1

'ftell() 'पाइप जैसे अवांछित धाराओं पर काम करने की संभावना नहीं है, वैसे भी। – caf

+0

मैं आपके डेटा के लिए मूल प्रोटोकॉल बनाने और फिर 'fgets() 'के बजाय' fread()' का उपयोग करने के साथ सहमत हूं। यह [उत्तर] (http://stackoverflow.com/questions/2870549/fifos-implementation/2871538#2871538) [एफआईएफओ कार्यान्वयन] पर एक प्रश्न के लिए (http://stackoverflow.com/q/2870549/203667) अतिरिक्त उपयोग हो सकता है क्योंकि यह कुछ उदाहरण प्रदान करता है कि इस तरह के प्रोटोकॉल का निर्माण कैसे किया जा सकता है। – jschmier

+0

फ़्रेड() सही काम करता है। धन्यवाद – Patryk

0

विश्वसनीय रूप से डेटा का आदान-प्रदान? इससे मुझे 0 एमक्यू (ज़ीरोएमक्यू) लाइब्रेरी के बारे में सोचना पड़ता है: http://zeromq.org

एक नज़र डालें, और बोनस के रूप में आपकी प्रक्रिया दूरस्थ कंप्यूटरों पर भी बात करने में सक्षम होगी।

क्लाउड में आपका स्वागत है।

2

आम तौर पर प्रक्रियाओं में बाइनरी structs का आदान-प्रदान करने के लिए fread और fwrite का उपयोग करेगा। यह निश्चित लंबाई रिकॉर्ड के लिए बहुत अच्छा काम करता है, और नल भेजने आदि में कोई समस्या नहीं है।

मुझे अपने लंबे करियर पर पता चला है कि अधिकांश अनुप्रयोगों में बाइनरी डेटा के बजाय एसीआई स्ट्रिंग्स, आसानी से पारदर्शी (उदाहरण के लिए scanf) का आदान-प्रदान करना बेहतर होता है। इस तरह संदेशों को देखा और लॉग किया जा सकता है, और व्यक्तिगत प्रक्रियाओं का परीक्षण टेलनेटिंग और टाइपिंग (आमतौर पर पेस्टिंग) द्वारा किया जा सकता है। अगर प्रोग्रामर केवल संदेश यातायात पढ़ सकता है तो यह सिर्फ विकास करना आसान बनाता है।