How to end inputstream.read in java - java

I am trying to read data from 5 devices connected serially. My Java code is running fine if the device is healthy, if not then inputstream.read() hangs the program and does not allow further execution.
I have tried using inputstream.available(), BufferedInputStream... but nothing works.
What I want to do is: if a device does not respond my code, it should end itself and let the control go to the main program where it will go to the next device. The socket remains open for one cycle of polling.
Socket es = new Socket("10.12.90.153",4001);
OutputStream osnew= es.getOutputStream();
InputStream isnew = new BufferedInputStream(es.getInputStream());
This is done in the task program, then I pass osnew and isnew to each device at a gap of one second for further action. The osnew writes some data to which the device responds. Then I read from isnew...This where the program hangs.

InputStream is designed to block when you try and read data and none is available. You could call the available() method to see whether any data is available to read without blocking, but this only works one way - if available() returns non-zero you know you can read without blocking, but if it returns zero you won't necessarily be blocked. It is perfectly valid for an input stream to always return zero from available().
You may wish to look into the non-blocking I/O APIs of java.nio instead of using streams.

You could handle each device in a separate thread. That way your program will stay responsive even when the devices aren't. But be aware of the pitfalls of multithreaded programming.
More information about multi-threaded programming in Java can be found on http://docs.oracle.com/javase/tutorial/essential/concurrency/

How are you reading from the device? I'll assume you're using some form of FileInputStream to do it. That class looks to be suitable for reading from a filesystem to me, but a device, which could block for a long period of time is likely to lock up the Java thread until the device does respond. You need to make some kind of timed read request of the device, and I don't know of any Java class that does that.
Best suggestion I have is to write some JNI code that talks nicely and doesn't block when your devices stop responding. This is what I did when I was talking to a USB device. If I were coding this (for Linux) I would use select (which has a time period argument) to wait of an input from any of the devices.

Related

Android USB Accessory Multi Thread

I have a problem caused by multi-threading and Android Open Accessory.
I need to communicate with a USB Accessory, but I need to do it from 2 threads. One thread generates and sends data the other one reads data.
Why I don't use a single thread? Because there can be 1 or more writes before a read and reads are blocking, so that is not an option.
If using multiple threads, I do run into "I/O Error (No such device)" sooner or later, because I will have a collision between read & write being executed at the same time.
Locking will more or less put me back in single-thread situation, so not good.
.available() method on the input-stream returns is not supported, so I cannot check if anything is available before doing a read
Since it's not a socket-based stream I cannot set timeout either.
I have tried getting the FileDescriptor from the USBAccessory and passing to JNI to handle it there, but after the first read/write the device becomes inaccessible.
Question/Suggestion needed:
What will be a suggested/best-practice approach to this? I do not expect written code, I just need some guidance on how to approach this problem.
To clarify:
The software at the other end might or might NOT respond with any data. There are some so called silent sends were the data sent it's just received but there is no ACK. Since the app I'm working on is only a proxy, I do not have a clear picture if the data will or will not produce an answer. That will require analysis of the data as well, which isn't on the books at the moment.
As you want to do read and write in parallel, writing will always lead to a pause to read if the read is on the same part as write.
May be you can follow similar approach as ConcurrentHashMap and use different locks for different segments and lock read only if write is on the same segment else allow the read to happen.
This will
Avoid blocking read during write in most scenarios
Avoid collision and
Definitely wont be a single thread approach.
Hope that helps.
If using multiple threads, I do run into I/O Error (No such device)
sooner or later, because I will have a collision between read & write
being executed at the same time.
This says it all. Since you are doing read and write on the same channel that does not support concurrent access, you are required to have your thread wait until the other thread is done doing read/write.
Your two-thread approach is what I would do, more or less. Good luck and trust in yourself.

How does Java NIO's selector check for available events under the hood?

A similar question has been asked before, but I would like to place it again, hoping that someone would help clear out a couple of things. As an experiment, I tried writing a naive "non-blocking" server in Java without using NIO, where essentially three threads are needed:
Main server thread - accept()s new socket connections, and puts each new socket in a queue
Reading worker thread - goes through each socket in the queue, and reads a little bit out of each socket's input stream, and stores it in an InputQueue
Writing worker thread - depending on when the incoming request gets read out of each socket, this worker would loop over all sockets where a response is needed, and once again, write a few bytes of response on every take.
In the previous question, it was pointed out that Java NIO's select() mechanism is far better than polling on each socket, and sleeping a little after every take through the queue. I know how select works in theory, but the main thing that I struggle to understand is the following: if polling is bad and inefficient, how does select() do it under the hood?
UPDATE: I found this page which gives a bit more light on how the native select() works under the hood. What is interesting is that indeed, my initial speculations seem to be right: select() works in a linear fashion, probing each of the requested file descriptors, similar to what a polling mechanism would do:
They both [select() and poll()] handle file descriptors in a
linear way. The more descriptors you ask them to check, the slower
they get. As soon as you go beyond perhaps a hundred file descriptors
or so - of course depending on your CPU and hardware - you will start
noticing that the mere waiting for file descriptor activity and the
following checking which file descriptor that it was, takes a
significant time and becomes a bottle neck.
It calls the select() method in the operating system, which:
deems a socket to be readable if there is data or a FIN in the socket receive buffer
deems a socket to be writable is there is space in the socket send buffer (i.e. most of the time).

Java: A FileInputStream that blocks in read() while other thread downloads remainder of file?

I have an FFmpeg-based video-playing app which is able to play content from any arbitrary InputStream.
It is important that the app is able to play a video file which is in the process of being downloaded. What I seem to need for this is a special kind of FileInputStream that will (a) share file access with the downloading thread, and (b) if it reaches the end of the downloaded portion, will quietly block until more content becomes available.
(a) seems easy enough thanks to RandomAccessFile, but I'm a bit puzzled about (b). I can probably hack something up that will work, but I am wondering if there's a standard approach to implementing this. Thinking about it in detail gives me a feeling that I may be missing something obvious.
Any thoughts? How would you guys do this?
If you can push the data not in the file but into a OutputStream (or maybe write simulataneously to both FileOutputStream and other shared PipedOutputStream), this would be the easiest solution:
Use PipedOutputStream and PipedInputStream. This will allow you to implement both A and B, however you will need to somehow implement video buffering on the viewer side.
Basically your downloader thread will write every bit of data it gets to the PipedOutputStream. The write() method is not blocking, as the data is pushed to the internal buffer of the pipe.
Your viewer thread will simply read() from the pipedInputStream, as here is what the API says: This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.
You have to poll the length of the file. There is no way to block waiting for the length of the file to change using the file alone. You can busy poll, or poll every 10 or 100 ms.
If the writer and reader are in the same process, you can use locking/synchronized blocks to notify the reader when more data has been added.
With multiple processes, you could use a socket to either send the data, or at least notify when the length has changed allowing the reader to block.
In case you do not control the download process, and want to play just ANY downloading file (even by some other downloaders) then you can Watch directory for changes.
It needs to be mentioned that this method is cross-platform and cross-filesystem. Here's quote from the same article:
Most file system implementations have native support for file change notification. The Watch Service API takes advantage of this support where available. However, when a file system does not support this mechanism, the Watch Service will poll the file system, waiting for events.
I believe there is no real answer to this question. I've got something which works, but it looks like inelegant hacking to me. Perhaps sometimes that's inevitable.

java socket / output stream writes : do they block?

If I am only WRITING to a socket on an output stream, will it ever block? Only reads can block, right? Someone told me writes can block but I only see a timeout feature for the read method of a socket - Socket.setSoTimeout().
It doesn't make sense to me that a write could block.
A write on a Socket can block too, especially if it is a TCP Socket. The OS will only buffer a certain amount of untransmitted (or transmitted but unacknowledged) data. If you write stuff faster than the remote app is able to read it, the socket will eventually back up and your write calls will block.
It doesn't make sense to me that a write could block.
An OS kernel is unable to provide an unlimited amount of memory for buffering unsent or unacknowledged data. Blocking in write is the simplest way to deal with that.
Responding to these followup questions:
So is there a mechanism to set a
timeout for this? I'm not sure what
behavior it'd have...maybe throw away
data if buffers are full? Or possibly
delete older data in the buffer?
There is no mechanism to set a write timeout on a java.net.Socket. There is a Socket.setSoTimeout() method, but it affects accept() and read() calls ... and not write() calls. Apparently, you can get write timeouts if you use NIO, non-blocking mode, and a Selector, but this is not as useful as you might imagine.
A properly implemented TCP stack does not discard buffered data unless the connection is closed. However, when you get a write timeout, it is uncertain whether the data that is currently in the OS-level buffers has been received by the other end ... or not. The other problem is that you don't know how much of the data from your last write was actually transferred to OS-level TCP stack buffers. Absent some application level protocol for resyncing the stream*, the only safe thing to do after a timeout on write is to shut down the connection.
By contrast, if you use a UDP socket, write() calls won't block for any significant length of time. But the downside is that if there are network problems or the remote application is not keeping up, messages will be dropped on the floor with no notification to either end. In addition, you may find that messages are sometimes delivered to the remote application out of order. It will be up to you (the developer) to deal with these issues.
* It is theoretically possible to do this, but for most applications it makes no sense to implement an additional resyncing mechanism on top of an already reliable (to a point) TCP/IP stream. And if it did make sense, you would also need to deal with the possibility that the connection closed ... so it would be simpler to assume it closed.
The only way to do this is to use NIO and selectors.
See the writeup from the Sun/Oracle engineer in this bug report:
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4031100

J2ME, InputStream hangs up after receving 40K of data over Bluetooth

On sending data over bluetooth from PC to my mobile(N73), the Input Stream seems to hang up.
InputStream is derived from StreamConnection.
PC software is built in VB.net.
Mobile in Java ME.
Does the InputStream have an internal buffer that needs to be emptied while reading large chunks of data?
Data is being received in chunks of 10Kb to 15Kb range, and the reading stops after receiving the 3rd chunk.
Strangely I am not receiving any exceptions.
I browsed through the InputStream class API documentation and couldn't find any InputStream clear or empty method.
There is only a reset() method, I don't know what its used for?
InputStream.reset() is a method you would call sometime after having used Inpustream.mark() to force the InputStream to create an internal buffer that would allow you to read the same data multiple times, assuming the InputStream supports it by returning true when calling InputStream.markSupported().
As far as the data transmission issue, we're talking about a handset running Series60 3rd edition on top of Symbian OS 9.1. Given how extensive the Symbian testing of JSR-82 was, an implementation bug as simple as a 40k limit on the InputStream seems unlikely.
Does the handset behavior change if the server sends smaller chunks at a much lower bitrate?
Does the handset process received data before reading some more?
What else is the MIDlet doing? Is everything else working as expected even after the bluetooth InputStream blocks?
I do remember a fairly important bug in the JSR-82 implementation that might have been fixed only after the initial N73 firmwares were created: do not use bluetooth at all in any event dispatching thread (not from any method like MIDlet.startApp(), Canvas.keyPressed(), CommandListener.commandAction(), PlayerListener.playerUpdate()...).
You are better off only using bluetooth from inside a Thread.run() method you wrote yourself.

Categories