2015-05-20 28 views
5

मैं एक सी एप्लीकेशन लिख रहा हूं जो बूट (distro: Arch Linux) पर systemd service के रूप में चलाया जाता है और जो सर्वर से कनेक्ट होगा। चूंकि एप्लिकेशन बूट पर चलाया जाता है, अंत में ऐसा होता है कि नेटवर्क कनेक्शन अभी तक स्थापित नहीं हुआ है। यह स्वाभाविक रूप से पहले कार्य की विफलता की ओर जाता है जिसके लिए एक की आवश्यकता होती है, जो मेरे मामले में getaddrinfo है।यदि गेटड्रिन्फो विफल रहता है तो यह हमेशा के लिए विफल रहता है (नेटवर्क तैयार होने के बाद भी)

तो मैंने सोचा कि मैं सिर्फ एक लूप लिखूंगा जो बार-बार getaddrinfo पर कॉल करता है जब तक कि यह नेटवर्क तैयार न हो जाए। दुर्भाग्य से मैंने पाया कि getaddrinfo कनेक्शन स्थापित होने के बाद भी name or service not known के साथ विफल रहता है।

मैं सर्वर को अपने होस्टनाम द्वारा पिंग करने में सक्षम हूं लेकिन getaddrinfo अभी भी ऐसा नहीं करेगा। अगर मैं एप्लिकेशन को रोकता हूं और इसे फिर से चलाता हूं, तो सब कुछ ठीक काम करता है। यदि पहले से पहले नेटवर्क कनेक्शन पहले से स्थापित है, getaddrinfo भी ठीक काम करता है।

जाहिर है, अगर getaddrinfo नेटवर्क विफल नहीं होने के कारण विफल रहा, तो यह हमेशा के लिए असफल हो जाएगा। ऐसा लगता है कि अब मौजूदा कनेक्शन से अवगत नहीं है। बहिष्कृत gethostbyname का उपयोग करते समय, व्यवहार वही है।

इस व्यवहार का कारण क्या है? क्या आंतरिक चर (यदि ऐसा मौजूद है) रीफ्रेश करने के लिए getaddrinfo को मजबूर करने का कोई तरीका है या ऐसा ही समझा सकता है कि फ़ंक्शन अभी भी क्यों मानता है कि कोई कनेक्शन नहीं है? क्या कोई अन्य कार्य है जिसे मुझे पहले जांचना चाहिए ताकि यह जांच सके कि नेटवर्क तैयार है या नहीं?

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

उत्तर

4

आप निम्न परीक्षण कार्यक्रम के संकलन, और नीचे दिए गए निर्देशों का पालन करते हुए जवाब समझ सकते हैं:

#include <sys/types.h> 
#include <sys/socket.h> 
#include <netdb.h> 
#include <stdio.h> 
#include <unistd.h> 

int main(int argc, char *argv[]) 
{ 
    while (1) 
    { 
     struct addrinfo *res; 
     int rc=getaddrinfo(argv[1], "http", NULL, &res); 

     printf("getaddrinfo returned %d\n", rc); 

     if (rc == 0) 
      freeaddrinfo(res); 

     sleep(1); 
    } 
} 

इससे पहले कि आप इस परीक्षण कार्यक्रम चलाने:

  1. कनेक्ट नेटवर्क के लिए।
  2. नाम बदलें, अस्थायी रूप से /etc/resolv.conf/etc/resolv.conf.save पर।
  3. एक अच्छा होस्टनाम का उपयोग करके, इस परीक्षण प्रोग्राम को शुरू करें।
  4. परीक्षण कार्यक्रम शुरू होने के तुरंत बाद, और त्रुटि कोड प्रिंट करना शुरू करता है, /etc/resolv.conf.save/etc/resolv.conf का नाम बदलें।
  5. निरीक्षण करें कि परीक्षण प्रोग्राम अभी भी DNS रिज़ॉल्यूशन विफलताओं की रिपोर्ट कर रहा है।
  6. यदि आप CTRL-C और इसे पुनरारंभ करते हैं, हालांकि, परीक्षण प्रोग्राम अब वैध DNS रिज़ॉल्यूशन की रिपोर्ट करेगा।

जब आप नेटवर्क से डिस्कनेक्ट और रीकनेक्ट करते हैं, तो आपका नेटवर्क स्टैक फिर से लिखता है और /etc/resolv.conf अपडेट करता है। सी कॉन्फ़िगरेशन फ़ाइल को सी लाइब्रेरी में DNS रिज़ॉल्वर द्वारा आवश्यक है। सी लाइब्रेरी पहली बार /etc/resolv.conf से DNS कॉन्फ़िगरेशन पढ़ती है, और इसे कैश करती है। यह प्रत्येक लुकअप के साथ जांच नहीं करता है, अगर /etc/resolv.conf की सामग्री बदल गई है।

अंत में

:

  1. आपका होमवर्क असाइनमेंट, res_init() के लिए एक कॉल, resolv.h में परिभाषित जोड़ने के लिए, इस परीक्षण कार्यक्रम के लिए इसी आदमी पृष्ठ को पढ़ने, और देखो क्या होता है। यह तुम्हारा जवाब है।
+0

इसके द्वारा, मेरा मतलब लूप के अंदर res_init() था। –

+0

वह वास्तव में कभी-कभी काम करता है (लेकिन शायद ही कभी)। मुझे लगता है कि यह काम करता है अगर नेटवर्क कनेक्शन पहले से स्थापित है, लेकिन 'resolv.conf' को अभी तक अपडेट नहीं किया गया है जब एप्लिकेशन शुरू हो गया है। एक बार 'resolv.conf' अपडेट हो जाने पर, लूप में' res_init' 'पर कॉल नई कॉन्फ़िगरेशन लोड करता है और फिर' getaddrinfo' suceeds लोड करता है। लेकिन यदि नेटवर्क कनेक्शन एप्लिकेशन स्टार्ट पर तैयार नहीं है, तो यह अभी भी असफल रहता है, – kassiopeia

+0

मेरे चरण-दर-चरण डेमो में एप्लिकेशन शुरू करना शामिल है जब कोई DNS रिज़ॉल्यूशन कॉन्फ़िगर नहीं किया गया है, जो तब होगा जब कोई नेटवर्क कनेक्शन मौजूद न हो। क्या आपने नेटवर्क कनेक्शन के बिना rs_init() को कॉल के साथ डेमो कोड शुरू करने का प्रयास किया था, और फिर किसी नेटवर्क से कनेक्ट किया था? यह छोटा सा डेमो कोड परीक्षण करने में काफी आसान है। कुछ भी मानने की जरूरत नहीं है। –

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