java - 蓝牙连接;无法正确发送字符串

标签 java android bluetooth inputstream outputstream

当我需要将字符串从我的服务器蓝牙套接字发送到我的客户端蓝牙套接字时,我的程序出现了问题。 只要我一次只发送一个字符串(例如聊天)一切正常,但如果我需要在短时间内编写更多字符串(以交换信息),字符串将不会与客户端代码分离.例如,如果我发送“FirstUser”,紧接着发送“SecondUser”,则客户端不会读取“FirstUser”,然后读取“SecondUser”。它将显示为“FirstUserSecondUser”。我怎样才能避免这种行为?

编辑:如果我让 Thread 在它能够发送新消息之前 hibernate ,它会读取正确的字符串,但此解决方案不能很好地满足我的需要。

服务器代码:发送给所有客户端(已编辑)

   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();
        }
    }

我感谢每一个小小的帮助:)。

最佳答案

您需要封装您的数据项以避免串联。 这意味着您必须在继续之前写入和读取整个数据项。

你应该有一些实用方法来做到这一点,而不是直接使用 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);
}

然后您可以使用这些方法让服务器和客户端读取和写入您的字符串项。

关于java - 蓝牙连接;无法正确发送字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8751797/

相关文章:

java - Java 是否有任何理由对同一类中的重载方法使用后期/静态绑定(bind)?

java - 为什么 CompletableFuture.runAsync() 并不总是提交给 ForkJoinPool.commonPool()?

flutter - 如何在 Flutter 中与 BLE 设备进行绑定(bind)

android - 将图像添加到 java2word 中的 Word 文档后出错

java - 如何有效地在 Android 图形中创建调色板颜色的显示位图?

flutter - 列出附近带有蓝牙功能的手机(flutter_blue包)

ios - 没有服务和特性的低功耗蓝牙是可能的吗?

java - 将 Hadoop 参数传递给 Java 代码

java ;初始化对象并传递对象

JAVA 正则表达式 : Match until the specific character