2012-03-12 9 views
8

मैं सर्वर-क्लाइंट एप्लिकेशन विकसित कर रहा हूं और मुझे इनपुट स्ट्रीम पर इनपुट डेटा की प्रतीक्षा करने में समस्या है।जावा इनपुटस्ट्रीम डेटा के लिए प्रतीक्षा करें।

मेरे पास इनपुट डेटा पढ़ने के लिए समर्पित धागा है। वर्तमान में यह डेटा उपलब्ध होने तक लूप को पकड़ने के दौरान उपयोग करता है। (एनबी प्रोटोकॉल निम्नानुसार है: पैकेट का आकार भेजें, एन कहें, int के रूप में फिर एन बाइट्स भेजें)।

public void run(){ 
    //some initialization 
    InputStream inStream = sock.getInputStream(); 
    byte[] packetData; 
    //some more stuff 
    while(!interrupted){ 
     while(inStream.available()==0); 
     packetData = new byte[inStream.read()]; 
     while(inStream.available()<packetData.length); 
     inStream.read(packetData,0,packetData.length); 
     //send packet for procession in other thread 
    } 
} 

यह काम करता है लेकिन थ्रेड को अवरुद्ध करता है जबकि लूप आईएमओ एक बुरा विचार है। मैं लूप द्वारा संसाधनों को लगातार उपभोग करने से रोकने के लिए Thread.sleep (X) का उपयोग कर सकता हूं, लेकिन निश्चित रूप से एक बेहतर तरीका होना चाहिए।

इसके अलावा मैं डेटा के हिस्से के रूप में थ्रेड को अवरुद्ध करने के लिए इनपुटस्ट्रीम.read पर भरोसा नहीं कर सकता, सर्वर द्वारा देरी के साथ भेजा जा सकता है। मैंने कोशिश की है लेकिन यह हमेशा अप्रत्याशित व्यवहार में हुआ।

मैं किसी भी विचार की सराहना करेंगे :)

+2

InputStream.read पहले से ही ब्लॉक जब डेटा उपलब्ध नहीं है । तो 'उपलब्ध' विधि को त्यागें। – UmNyobe

उत्तर

12

आप() DataInputStream.readFully उपयोग कर सकते हैं

DataInputStream in = new DataInputStream(sock.getInputStream()); 
//some more stuff 
while(!interrupted) { 
    // readInt allows lengths of up to 2 GB instead of limited to 127 bytes. 
    byte[] packetData = new byte[in.readInt()]; 
    in.readFully(packetData); 
    //send packet for procession in other thread 
} 

मैं NIO जो फिर से प्रयोग करने योग्य बफ़र्स का समर्थन करता है अवरुद्ध उपयोग करने के लिए पसंद करते हैं।

SocketChannel sc = 
ByteBuffer bb = ByteBuffer.allocateDirect(1024 *1024); // off heap memory. 

while(!Thread.currentThread.isInterrupted()) { 
    readLength(bb, 4); 
    int length = bb.getInt(0); 
    if (length > bb.capacity()) 
     bb = ByteBuffer.allocateDirect(length); 
    readLength(bb, length); 
    bb.flip(); 
    // process buffer. 
} 



static void readLength(ByteBuffer bb, int length) throws EOFException { 
    bb.clear(); 
    bb.limit(length); 
    while(bb.remaining() > 0 && sc.read(bb) > 0); 
    if (bb.remaining() > 0) throw new EOFException(); 
} 
+3

शायद आप अपनी स्मृति में 2 जीआईबी पढ़ना नहीं चाहते हैं –

4

रूप UmNyobe कहा, available() अगर आप न के रूप में डिफ़ॉल्ट व्यवहार ब्लॉक कर रहा है ब्लॉक करना चाहते हैं इस्तेमाल किया जा करने के लिए है।

बस सामान्य read का उपयोग पढ़ने के लिए जो कुछ भी उपलब्ध है, लेकिन अन्य धागा एक बार आप अपने बफर में packetData.length बाइट्स है में प्रसंस्करण के लिए केवल भेजने पैकेट ...

+0

धन्यवाद ... मेरा दिन बचाया। – Velu

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