09-02-2008 04:38 AM
Hi all,
I need a socket connection and its properties are:
1) Unfortunately, the server side code should not be changed.
2) I connect to server, i fetch data but,
server can send data at any time. For example, i connected to the server at time (t), then server sent me data at
(t + 5) and then sent datas at (t+6),(t+10),(t+45),(t+46)... and so on, and never(!) stop.
In this sense, I created a thread opens a socket connection and reads data from inputstream in infinite loop. it seems everything is OK. However, there is a problem! When i attemp to stop my application, the thread never stop even when i use the System.exit(0) , because inputstream.read blocks the thread. It waits a new data from server but server may be send it an hour later.
Anyway, what about my options? Well, i can't use READTIMEOUT, because server can send a data after time out.
i can't ignore this zombie thread. OK, send a knowledge to server, "Hey! i leave you" and server send me OK, but server won't understand since i can't change the server.
So, what can i do? I am so desperate! I need a non-blocking reading, or implemented isAvailable() function but i can't found.
Thanks for all you!
09-02-2008 05:34 AM
Let your thread to be a listener to the application events.
And when you're exiting your app - send an event to this thread.
In your infinite loop check that APP_QUIT event is not occured before and after blocking operations.
And if this event occured - just return from run() method.
09-02-2008 05:49 AM
Does it work? i confused because it is blocked by read at exactly hear;
in the thread,
while ( (len = inputStream.read( data ) ) != -1 ) {
Thanks for your reply!
09-02-2008 06:12 AM
Look at the following run() method snippet
public void run() { //...... boolean done; while (!done) { if(!isQuitRequested) { final int bytesRead = stream.read(...); done = (bytesRead==-1); } else { done = true; } } }
09-02-2008 06:34 AM
Yes, my code is something like that, also. However, it does not work. "read" method blocks, and does not return anything, just wait and wait upto receiving a data to the stream.
Thanks for your quick answers.
09-02-2008 08:25 AM
I think vona is right in that the read is difficult to 'break'. There has been a similar discussion on another thread pointing this out.
What rafo has suggested will terminate the thread, however if the read is not even being broken by System.exit(), this is not going to help. However I thought that a read() such as the one vona is attempting, was always timed out, after two minutes by default, so I'm very surprised if the read is permanently blocking. Vano are you sure that the read is never timed out?
Regardless, I have two suggestions:
1) Have a loop that checks inputStream.available() every few seconds. Only issue the read() when there is data to be read. In the loop that checks for available bytes, also check the 'terminate' flag.
2) Have a method that you call on the Thread to stop the Thread. In that method, close the inputstream. That should cause an exception on the read.
Don't know whether either of these will work, as I haven't tested. But worth a try.
09-03-2008 03:21 AM - edited 09-03-2008 03:25 AM
Thank you, peter! Actually i have tried these suggestions, but isAvailable always return 0. Also, api reference say the same thing.(By the way, why does not rim implement it? Or any suggestion about, how can we override it?).
The other issue, closing socket, outputstream, inputstream does not work, also. Yes, i have an exception but it does not break the read. it just say, you can't do it, you are not that thread. If i leave this job to my connection thread, it will never done. Because, it is blocked.
Well, the situation seems bad, but i have good news. Read timed out does its job. I have done some tests and the results say that, thread is killed at 120th second after System.exit is called. So, if i change READTIMEDOUT, i will be happy developer.
Thanks for all of you!
09-03-2008 04:39 AM - edited 09-03-2008 04:41 AM
Vano,
Thanks for letting us know the results of your tests on the options I had suggested - both were options that were on my list of things to try, because I have a related problem to resolve - I want to break a connection and start a new one when some high priority traffic comes in. Having re-read your posts, I note that you did say that you had tried available(), or isAvailable(), so apologies for suggesting something that you had already said you had tried.
Regarding READTIMEOUT, I presume you have seen
One other point. I remember reading, and I've no idea where or when, that keeping a TCP connection open like you are doing is not recommended. I think there are only 5 TCP connections possible, so your holding a connection might impact the BlackBerry or other applications. Also I've no idea how or even if holding a connection would impact or be impacted by Phone calls and other normal BB activity. If you have not already done so, I would get this onto a real device as soon as I could and make sure it all works fine. I'd be really interested in finding out how this goes, because, as noted above, I need to do something similar in the near future.
09-03-2008 07:42 AM