outputStream.write是否存在缓冲区溢出问题?

3
我正在尝试向串口发送一个byte[],但是outputstream.write(byte[]);仅在byte[].length小于约100字节时有效。以下是一些需要了解的信息:
  • 使用Spring Source Tool Suite(Eclipse)。
  • JDK 1.7。
  • DEFAULTBAUDRATE设置为9600。
  • byte[]永远不会超过476个字节。
  • NRSerial是一个库,提供了一个平台无关版本的“已故”的vaxx.comm库。
  • 没有硬件连接到串口。
  • 我正在使用类似Wireshark的应用程序对串口进行嗅探。
  • 我仍然是一名学生,所以代码可能有点糟糕 :P。
    以下是有效的代码:
    NRSerialPort port = new NRSerialPort(portname, DEFAULTBAUDRATE);
    port.connect();
    OutputStream outputStream = port.getOutputStream();
    for(int i = 0; i<bytes.length; i++){
        if(i%10==0){
            Thread.sleep(1);    
        }
        outputStream.write(bytes[i]);
    }
    outputStream.flush();
    outputStream.close();
    port.disconnect();
    

    优点:适用于所有系统
    缺点:可能会不必要地休眠

    这个也是如此:

    NRSerialPort port = new NRSerialPort(portname, DEFAULTBAUDRATE);
    port.connect();
    OutputStream outputStream = port.getOutputStream();
    for(byte b : bytes){
        outputStream.write(b);
    }
    outputStream.flush();
    outputStream.close();
    port.disconnect();
    

    优点:没有不必要的睡眠
    缺点:在快速系统上可能无法工作,因为它们可以更快地处理for each

    但是如果bytes包含超过约100个字节,则下面的代码将失败:

    NRSerialPort port = new NRSerialPort(portname, DEFAULTBAUDRATE);
    port.connect();
    OutputStream outputStream = port.getOutputStream();
    outputStream.write(bytes);
    outputStream.flush();
    outputStream.close();
    port.disconnect();
    

    尽管write(byte[])是sun库中的有效方法,但我对此有一些想法:
    • 我会溢出输出缓冲区,波特率太低无法一次性发送这些数据
    • write(byte[])不会将byte[]分成更小的部分
    也许您会想为什么会询问此问题,如果我已经拥有了一个可行的解决方案。好吧:
    我想知道我的哪个解决方案更好,或者是否还有其他/更好的方法来解决这个问题。此外,如果方法write(byte[])的处理能力取决于硬件,为什么不在JavaDoc中说明呢?

  • 你说代码失败了。它是怎么失败的?它是否引发了异常,或者你没有在套接字读取输出时接收到所有字节?你的问题需要更多的上下文。 - mcfinnigan
    “工作正常”的代码在嗅探器中显示如下: 由进程“javaw.exe”(PID:2060)打开的端口 3C 00 00 00 00 端口已关闭而那些仅仅打开和关闭端口的代码则不行。 - remyH
    你确定在这些代码片段之前,bytes[]数组已经正确地填充了吗?如果另一个流同时写入它,这可能会解释清楚。 - Lycha
    是的,我确定。除非在你的情况下,数组有多大都无关紧要。 - remyH
    1个回答

    0
    假设我已经谷歌了正确的代码,这看起来不像是Java的问题,而是与NRSerialPort库的实现有关。
    深入代码,我可以看到SerialOutputStream提供了OutputStream的实现,并根据使用write(byte)write(byte[])方法调用两种不同的方法:
    请参见此处
    protected native void writeByte( int b, boolean i ) throws IOException;
    protected native void writeArray( byte b[], int off, int len, boolean i ) 
        throws IOException;
    

    不用深入研究本地代码,我认为可能在实现writeArray方法时存在错误。


    我在nrserialport的维基上发布了这个bug,感谢您的帮助;) - remyH

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接