2012-01-06 10 views
6

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

संपादित करें: अगर मैं थ्रेड नींद को एक नया संदेश भेजने में सक्षम होने से पहले सोता हूं, तो यह सही तार पढ़ता है लेकिन यह समाधान मेरी ज़रूरत के लिए ठीक काम नहीं कर रहा है।

सर्वर-कोड: सभी ग्राहकों (संपादित) के लिए भेजने से

public synchronized void sendToAll(String message) 
{ 
    try { 
     Thread.sleep(100); 
    } catch (InterruptedException e1) { 
     e1.printStackTrace(); 
    } 

    publishProgress(message); 
    for(OutputStream writer:outputList) { 
     try { 
      writer.write(message.getBytes()); 
      writer.flush(); 
     } catch (IOException e) { 
      System.out.println("Some-Error-Code"); 
     } 
    } 
} 

सर्वर-कोड: एक ग्राहक से पढ़ने:

public void run() { 
    String nachricht; 
    int numRead; 
    byte[] buffer = new byte[1024]; 
    while (runningFlag) 
    { 
     try { 
      if((numRead = inputStream.read(buffer)) >= 0) { 
       nachricht = new String(buffer, 0, numRead); 
       serverThread.handleMessage(nachricht); 
      } 
      } 
      catch (IOException e) { 
       this.cancel(); 
       e.printStackTrace(); 
      } 
    } 
} 

क्लाइंट-कोड: सर्वर से पढ़ते (संपादित)

@Override 
    protected Void doInBackground(Integer... ints) {  
     String nachricht = new String(); 
     byte[] buffer = new byte[1024]; 
     int numRead; 
     while (runningFlag) 
     { 
      try { 
       if(((numRead = inputStream.read(buffer)) >= 0)) { 
        nachricht = new String(buffer, 0, numRead); 
        publishProgress(nachricht); 
       } 
      } 
      catch (IOException e) { 
       clientGame.finish(); 
       e.printStackTrace(); 
      }      
     } 
     return null; 
} 

क्लाइंट-कोड: सर्वर पर लिखना

public synchronized void write(String nachricht) 
    { 
     try { 
      Thread.sleep(100); 
     } catch (InterruptedException e1) { 
      e1.printStackTrace(); 
     } 

     try { 
      outputStream.write(nachricht.getBytes()); 
      outputStream.flush(); 
     } catch (IOException e) { 
      this.cancel(); 
      e.printStackTrace(); 
     } 
    } 

मैं हर छोटी मदद की सराहना करता हूं :)।

+0

क्या आपका सर्वर क्लाइंट को भेजता है या इसके विपरीत? –

+0

दोनों तरीकों के दौर। क्लाइंट या सर्वर एक और स्ट्रिंग भेजने में सक्षम होने से पहले मैंने Thread.sleep (100) के साथ समस्या को अस्थायी "हल किया"। लेकिन यह वास्तव में एक साफ समाधान नहीं है। – Refrigerator

+0

क्या आप सभी भेजे गए संदेशों को फ़्लश कर रहे हैं? –

उत्तर

8

आपको concatenation से बचने के लिए अपने डेटा आइटम को समाहित करने की आवश्यकता है। इसका मतलब है कि आपको जारी रखने से पहले एक संपूर्ण डेटा आइटम लिखना और पढ़ना है।

आप सीधे OutputStream और InputStream के तरीकों का उपयोग कर के बजाय ऐसा करने के लिए कुछ उपयोगिता तरीकों होना चाहिए:

public static void writeItem(OutputStream out, String s) throws IOException 
{ 
    // Get the array of bytes for the string item: 
    byte[] bs = s.getBytes(); // as bytes 
    // Encapsulate by sending first the total length on 4 bytes : 
    // - bits 7..0 of length 
    out.write(bs.length);  // modulo 256 done by write method 
    // - bits 15..8 of length 
    out.write(bs.length>>>8); // modulo 256 done by write method 
    // - bits 23..16 of length 
    out.write(bs.length>>>16); // modulo 256 done by write method 
    // - bits 31..24 of length 
    out.write(bs.length>>>24); // modulo 256 done by write method 
    // Write the array content now: 
    out.write(bs); // Send the bytes 
    out.flush(); 
} 

public static String readItem(InputStream in) throws IOException 
{ 
    // first, read the total length on 4 bytes 
    // - if first byte is missing, end of stream reached 
    int len = in.read(); // 1 byte 
    if (len<0) throw new IOException("end of stream"); 
    // - the other 3 bytes of length are mandatory 
    for(int i=1;i<4;i++) // need 3 more bytes: 
    { 
     int n = in.read(); 
     if (n<0) throw new IOException("partial data"); 
     len |= n << (i<<3); // shift by 8,16,24 
    } 
    // Create the array to receive len bytes: 
    byte[] bs = new byte[len]; 
    // Read the len bytes into the created array 
    int ofs = 0; 
    while (len>0) // while there is some byte to read 
    { 
     int n = in.read(bs, ofs, len); // number of bytes actually read 
     if (n<0) throw new IOException("partial data"); 
     ofs += n; // update offset 
     len -= n; // update remaining number of bytes to read 
    } 
    // Transform bytes into String item: 
    return new String(bs); 
} 

तो फिर तुम दोनों के लिए सर्वर & ग्राहक इन पद्धतियों का उपयोग करता है और अपने स्ट्रिंग आइटम लिखने के लिए।

+0

आउटपुटस्ट्रीम.फ्लश() के प्रलेखन के बारे में "यह कार्यान्वयन कुछ भी नहीं करता है।" यह सामान्य है क्योंकि आउटपुटस्ट्रीम केवल एक सार वर्ग है। वास्तविक वर्ग (FileOutputStream, सॉकेटऑटपुटस्ट्रीम, ...) कुछ करने के लिए इस विधि को ओवरराइड करें। –

+0

मैं आपका कोड समझ नहीं सकता। क्या आप इसे समझाने की कोशिश कर सकते हैं? उदाहरण के लिए मैंने पहले कभी '>>>' और '| =' ऑपरेटर कभी नहीं देखा है। और वहां एक समझौता क्यों है? फ्लश() समस्या का समाधान क्यों नहीं करता है? – Refrigerator

+0

फ़्लश() डेटा प्राप्त करने के समय वारंटी नहीं दे सकता क्योंकि आप सॉकेट का उपयोग कर रहे हैं, और ओएसआई परतों और प्रणालियों के बीच कई इंटरमीडिएट बफर हैं। –

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