Ziver / Netty-Transport-jSerialComm

A Netty transport for serial communications using the jSerialComm library
27 stars 12 forks source link

java.io.IOException: The read operation timed out before any data was returned. #2

Open felixunivers opened 6 years ago

felixunivers commented 6 years ago

Hi, I am trying your jSerialComm with Netty solution - the example and am running into this error: "java.io.IOException: The read operation timed out before any data was returned." It gets thrown by jSerialComm class: private final class SerialPortInputStream extends InputStream method: public final int read(byte[] b, int off, int len) throws NullPointerException, IndexOutOfBoundsException, IOException section:

// Read from the serial port
int numRead = readBytes(portHandle, b, len, off);
    if (numRead == 0)
        throw new IOException("The read operation timed out before any data was returned.");

When I use jSerialComm on its own on the same port it performs fine.

Any ideas ?

felixunivers commented 6 years ago

A little more detail: on the line: int numRead = readBytes(portHandle, b, len, off); len = 1; but the method returns 0 (zero) - it cannot or does not read the port data

Ziver commented 5 years ago

Hi, Sorry for the very late response.

Have you tried updating the timeout, jSerialComm tend to have shorter timeouts and return without reading any data.

georgecao commented 5 years ago

@Ziver I see the same error message. OIO implementation use only one thread for reading or writing data. So if the device do not send any data immediately after you open the port, the entire channel will be blocked due to the autoRead option is on by default. Then you are blocked, you do NOT read anything from the input stream and you cannot write anything to the output stream b/c the only thread is blocked for reading data. Seams there is no solution to this one, beside ,OIO is deprecated by Netty too, we need a NIO implementation, right?

georgecao commented 5 years ago

@felixunivers find any way to fix this?

gsrunion commented 4 years ago

https://github.com/Fazecast/jSerialComm/wiki/Java-InputStream-and-OutputStream-Interfacing-Usage-Example

Set the read timeout to zero and the exception won't be thrown. You may also have to the use the mode of operation stated there. Netty closes the channel when an exception is thrown that is a subclass of IOException, which this SerialTimeoutException is.

gsrunion commented 4 years ago

Update: While my solution keeps the SerialTimeoutException from firing it is still subject to the deadlock issue @georgecao describes above. The problem with the SerialTimeoutException is that is subclasses, ultimately, IOException and when an exception is thrown that is a subclass Netty brings down the channel. Still looking for a workaround at this point.

gsrunion commented 4 years ago

I have a PR against JSerialComm to add an option to suppress timeout exceptions when reading from the inputstream.

https://github.com/Fazecast/jSerialComm/pull/288/commits/eab394dde1b6dd4a561926b9c996669dd9104a1c

I also made changes to my local fork of this repo to set that option. Things seem to work.

Ziver commented 4 years ago

Another solution if the PR on jSerialComm takes longer to merge or does not get merged would be to wrap the serial inputstream in a wrapper where we catch and ignore the SerialTimeoutException exception.

gsrunion commented 4 years ago

Yes. But exceptions are generally considered expensive and the more optimum solution would be to not throw them at all.

Ziver commented 4 years ago

I agree, the best solution is if your PR on jSerialComm is merged.

LisaU commented 4 years ago

@felixunivers find any way to fix this?

Hi,NIO implementation, Is it feasible?

gsrunion commented 4 years ago

NIO....probably but there are few examples and even less documentation about how to implement an NIO channel. I know it comes down to implementing an interface but without a good writeup or example to worn from you have to make a lot of assumptions about what the expected behavior for the methods are.