2012-03-13 9 views
9

तो मैं गो में अपने लिफ्ट के लिए एक सर्वर बना रहा हूं, और मैं एक "टीसीपी-कनेक्शन के साथ एक goroutine के रूप में" हैंडलर "समारोह चला रहा हूँ। मैं इसे किसी कनेक्शन से पढ़ना चाहता हूं, और यदि किसी निश्चित समय के भीतर कोई सिग्नल नहीं मिला है, तो मैं इसे एक त्रुटि वापस करना चाहता हूं।मैं नेट कैसे बना सकता हूं। गोलांग में इनपुट के लिए प्रतीक्षा करें?

func handler(conn net.Conn){ 
    conn.SetReadTimeout(5e9) 
    for{ 
     data := make([]byte, 512) 
     _,err := conn.Read(data) 
    } 
} 

जब तक ग्राहक त्रुटि EOF net.Read समारोह रिटर्न भेजने बंद हो जाता है और शुरू होता है कोई देरी से पाशन के रूप में मैं एक ग्राहक कनेक्शन यह ठीक काम कर रहा है से अधिक सामान भेजने, लेकिन जैसे ही है ।

यह हो सकता है कि रीड कैसे काम करना चाहिए, लेकिन क्या कोई समस्या को संभालने और कनेक्शन को खोलने के बिना समस्या को संभालने का एक और तरीका सुझा सकता है जब भी मैं कुछ पढ़ना चाहता हूं?

+2

conn.SetReadTimeout (5e9) वह नहीं है जो आप चाहते हैं। SetReadTimeout एक पूर्ण समय की अपेक्षा करता है, एक अवधि नहीं। "Time.Seconds * 10" के रूप में निर्दिष्ट करने का प्रयास करें और संकलक शिकायत करेगा। आप ऊपर क्या कह रहे हैं कि आप 1 जनवरी 1 9 70 के बाद कनेक्शन को 5000 सेकेंड पर समय से बाहर करना चाहते हैं। तो यह बिल्कुल इंतजार नहीं करेगा। इसके बजाय आप दस सेकंड टाइमआउट के लिए conn.SetReadTimeout (time.अब() जोड़ें (समय। सेकंड * 10)) के प्रभाव के लिए कुछ चाहते हैं। – Crunge

उत्तर

19

पढ़ना अपेक्षित काम के रूप में काम कर रहा है। ऐसा लगता है जैसे आप नेट चाहते हैं। जाओ में एक चैनल की तरह काम करने के लिए पढ़ें। सिर्फ एक चल goroutine में net.Read लपेट और चैनलों से पढ़ने के लिए एक goroutine वास्तव में सस्ती है चयन विकल्प का उपयोग और इसलिए एक चैनल

उदाहरण है इस बार में बहुत आसान है:

ch := make(chan []byte) 
eCh := make(chan error) 

// Start a goroutine to read from our net connection 
go func(ch chan []byte, eCh chan error) { 
    for { 
    // try to read the data 
    data := make([]byte, 512) 
    _,err := conn.Read(data) 
    if err != nil { 
     // send an error if it's encountered 
     eCh<- err 
     return 
    } 
    // send data if we read some. 
    ch<- data 
    } 
}(ch, eCh) 

ticker := time.Tick(time.Second) 
// continuously read from the connection 
for { 
    select { 
    // This case means we recieved data on the connection 
    case data := <-ch: 
     // Do something with the data 
    // This case means we got an error and the goroutine has finished 
    case err := <-eCh: 
     // handle our error then exit for loop 
     break; 
    // This will timeout on the read. 
    case <-ticker: 
     // do nothing? this is just so we can time out if we need to. 
     // you probably don't even need to have this here unless you want 
     // do something specifically on the timeout. 
    } 
} 
+2

प्रलेखन इस तरह से ['time.Tick'] (https://golang.org/pkg/time/#Tick) का उपयोग करने के खिलाफ स्पष्ट रूप से चेतावनी देता है। –

+0

@ डेवसी: मैंने एक सिंगल टिकर का उपयोग करने के लिए कोड अपडेट किया। – nfirvine

+0

इसके अलावा, मैं कहूंगा कि एक सेकंड की तुलना में बहुत छोटा मूल्य अधिक उपयुक्त होगा। – nfirvine

0

यह संभव है कि कचरा कलेक्टर (जीसी) कनेक्शन के एक छोर बंद कर देता है क्योंकि net.Conn जीसी दृष्टिकोण से किसी न पहुंचने योग्य वस्तु बन जाता है। इसे रोकने के लिए: क्लाइंट भेजने के बाद, सुनिश्चित करें कि क्लाइंट कनेक्शन एक चर में संग्रहीत है जो आपके कोड द्वारा सुलभ है।

एक और विकल्प यह है कि आपके प्रोग्राम में कहीं भी आप इसके बारे में जानने के बिना कनेक्शन के एक छोर को बंद कर रहे हैं।

+0

मैंने सोचा कि आप गलत थे, लेकिन मुझे लगता है कि आप सही हो सकते हैं। तो मुझे एटीएम को अनदेखा करने की अनुमति नहीं दे रहा है। – nfirvine

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