2012-03-09 12 views
12

भेजने से पहले टीसीपी डेटा बफर करने के लिए मजबूर कर रहा है। मेरे पास जावा टीसीपी गेम सर्वर है, मैं java.net.ServerSocket का उपयोग करता हूं और सब कुछ ठीक चलता है, लेकिन हाल ही में मेरे आईएसपी ने कुछ प्रकार का अपग्रेड किया है, जहां, यदि आप दो भेजते हैं एक ही टीसीपी कनेक्शन के लिए पैकेट बहुत तेज़ होते हैं, वे इसे बलपूर्वक बंद करते हैं।मेरा आईएसपी मुझे

यही कारण है कि मेरी खिलाड़ियों का एक बहुत बेतरतीब ढंग से डिस्कनेक्ट हो जाते हैं जब वहाँ खेल में यातायात का एक बहुत है

(जब वहाँ संभावना है कि सर्वर एक ही व्यक्ति के लिए एक ही समय में 2 पैकेट भेज देंगे की एक बहुत कुछ है) यहाँ मैं क्या मतलब का एक उदाहरण है: मैं कुछ इस तरह करते हैं, मेरी आईएसपी दोनों क्लाइंट और सर्वर पक्ष को बिना किसी कारण के कनेक्शन बंद हो जाएगा:

tcpOut.print("Hello."); 
tcpOut.flush(); 

tcpOut.print("How are you?"); 
tcpOut.flush(); 

लेकिन यह ठीक से काम करेंगे अगर मैं कुछ करना इस तरह:

tcpOut.print("Hello."); 
tcpOut.flush(); 

Thread.sleep(200); 

tcpOut.print("How are you?"); 
tcpOut.flush(); 

या इस:

tcpOut.print("Hello."); 
tcpOut.print("How are you?"); 
tcpOut.flush(); 

यह केवल कुछ हफ़्ते पहले शुरू हुई जब वे (आईएसपी) सेवा और नेटवर्क के लिए कुछ परिवर्तन किया था। मैंने Wireshark का उपयोग करके देखा कि आपके पास एक ही टीसीपी कनेक्शन के लिए दो पैकेट के बीच कम से कम ~ 150ms समय होना चाहिए या फिर यह बंद हो जाएगा।

1) क्या आप जानते हैं कि इसे क्या कहा जाता है? क्या इसका नाम भी है? क्या यह कानूनी है? send(PrintWriter out, String packetData);

2) क्या कोई आसान समाधान से पहले ही ग्राहकों को भेज देता है डेटा बफ़र होना जावा पूछने के लिए है:

अब मैं जानते हुए भी कि मैं एक विधि कहा जाता है का उपयोग अपने खेल सर्वर को फिर से लिखने के लिए है? या पूरी चीज को फिर से लिखने के बिना प्रत्येक भेजने से पहले 150 मिमी प्रतीक्षा करें? मैंने कुछ googling किया लेकिन मुझे इस समस्या से निपटने वाली कुछ भी नहीं मिल रही है। इसके बारे में मदद करने के लिए कोई सुझाव या जानकारी वास्तव में सराहना की जाएगी, बीटीडब्ल्यू गति अनुकूलन बहुत महत्वपूर्ण है। धन्यवाद।

+1

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

+1

आपकी टिप्पणी के लिए ईजेपी धन्यवाद। मैं 100% सकारात्मक हूं, आईएसपी कनेक्शन बंद कर रहा है, जब मैं लाल रीसेट पैकेट प्राप्त करता हूं तो मैं इसे वायरशर्क पर देखता हूं। मैंने कुछ परीक्षण भी किए .. कभी-कभी डेटा को एक पैकेट में जोड़ा जाता है जैसा कि आपने अभी कहा था (स्थानीय टीसीपी/आईपी स्टैक) लेकिन कभी-कभी ऐसा नहीं होता है जब मेरे सर्वर के पास फ्लश करने के लिए बहुत कुछ है। यह एक एमएमओआरपीजी गेम है, इसलिए जब उपयोगकर्ता मानचित्र पर एक ही समय में बात करते हैं, स्थानांतरित करते हैं, हमला करते हैं, तो फ्लशिंग करने के लिए बहुत कुछ होता है, इसलिए किसी बिंदु पर दो पैकेट एक ही समय में एक खिलाड़ी को भेजे जाते हैं, और मेरा आईएसपी बंद हो जाता है वह सॉकेट – Reacen

+0

और "एक ही समय" से मेरा मतलब 100 एमएमएस से कम देरी के साथ है। – Reacen

उत्तर

3

आप अंतिम flush कॉल टाइमस्टैम्प का ट्रैक रखने के लिए Writer रैपर कार्यान्वयन बना सकते हैं। लगातार दो फ्लश के बीच 150 एमएस देरी का सम्मान करने के लिए प्रतीक्षा कॉल जोड़ना एक त्वरित कार्यान्वयन है।

public class ControlledFlushWriter extends Writer { 
    private long enforcedDelay = 150; 
    private long lastFlush = 0; 
    private Writer delegated; 

    public ControlledFlushWriter(Writer writer, long flushDelay) { 
     this.delegated = writer: 
     this.enforcedDelay = flushDelay; 
    } 

    /* simple delegation for other abstract methods... */ 

    public void flush() { 
     long now = System.currentTimeMillis(); 
     if (now < lastFlush + enforcedDelay) { 
      try { 
       Thread.sleep(lastFlush + enforcedDelay - now); 
      } catch (InterruptedException e) { 
       // probably prefer to give up flushing 
       // instead of risking a connection reset ! 
       return; 
      } 
     } 
     lastFlush = System.currentTimeMillis(); 
     this.delegated.flush(); 
    } 

} 

अब यह रैप करने के लिए पर्याप्त होना चाहिए अपने मौजूदा इस ControlledFlushWriter साथ PrintWriter काम के आसपास करने के लिए अपने आईएसपी क्यूओएस अपने सभी आवेदन को फिर से लिखकर बिना।

आखिरकार, यह झंडा एक कनेक्शन तत्काल के रूप में अपनी पैकेट के किसी भी ... इस तरह के एक हालत में बचाने के लिए उचित लगता है, इसे लागू करने के एक निष्पक्ष क्यूओएस लिंक साझाकरण मुश्किल है।

+0

बहुत बहुत धन्यवाद! – Reacen

5

यदि आपका आईएसपी ऐसी सेवा नीतियों की गुणवत्ता को लागू करता है और आपके पास उनके साथ बातचीत करने का कोई तरीका नहीं है, तो मैं आपको टीसीपी/आईपी स्टैक क्यूओएस कॉन्फ़िगरेशन के साथ भी अपने पक्षों के नियमों को लागू करने का प्रस्ताव करता हूं।

फ्लश आपके टीसीपी पैकेट को तत्काल (यूआरजी ध्वज) के रूप में चिह्नित करता है ताकि यह बफर/टीसीपी विंडो स्थिति जो कुछ भी भेजा जा सके। अब आप लाइन पर अपने ऑपरेटिंग सिस्टम या किसी भी नेटवर्क उपकरण बताने के लिए है करने के लिए या तो

  • उपेक्षा (या बस रीसेट) तत्काल झंडा जब पिछले पैकेट पिछले 150 एमएस में भेज दिया गया है और कुछ बफरिंग कर यदि आवश्यक हो तो
  • 150 एमएस बाधा का सम्मान करने के लिए लगातार तत्काल पैकेट की डिलीवरी में देरी।

शायद विंडोज के लिए एक महंगा सॉफ्टवेयर ऐसा करने के लिए मौजूद है। व्यक्तिगत रूप से, मुझे लगता है कि आपके विंडोज वर्कस्टेशंस और मॉडेम के बीच राइटर के रूप में एक लिनक्स बॉक्स डालने के लिए iptables में appropriate QoS settings और qdisc चाल चलेंगे।

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