How to close socket...
Hi,
I am using this
import java.io.*;
import java.net.*;
private Socket sock;
private BufferedReader in;
ServerSocket ss =new ServerSocket(TCP_PORT);
Socket sock = ss.accept();
in =new BufferedReader(new InputStreamReader(sock.getInputStream()));
If I am reading something within.readLine(); (I am waiting for something), but in another thread I am trying to close socket and BufferedReader with
in.close();
sock.close();
it froze thread or I should wait to much to close it and go on. What I should do to close socket, how I can tell to bufferedReade to stop waiting for response? I hope I was enough clear :-|
Thank you.
[953 byte] By [
boba5555a] at [2007-11-26 23:00:28]

# 1
Use a read timeout on the read so it won't block forever; if you get a timeout and the socket is still open, loop.
ejpa at 2007-7-10 13:06:39 >

# 2
Sorry I didn't replay before.Which procedure should I use to set timeout for this problem?How do you think "loop"?Thank you.
# 3
Socket.setSoTimeout().Do you really not know what 'loop' means in computer programming?
ejpa at 2007-7-10 13:06:39 >

# 4
> Do you really not know what 'loop' means in computer
> programming?
Yes :) When we talk about art of programing, believe me that I know much about that (basic stuff like binary search, sorting, then DP, graphs, data structures like binary trees - avl, rb; interval trees, cumulative tables), so it is obviously I know what means 'loop' (go through some part of code while some conditions are satisfied), but I don't know what I really should do in this case.
# 5
If you still can't understand what I said in reply #1 I don't think I can help you any further.
ejpa at 2007-7-10 13:06:39 >

# 6
Something like thiswhile (socket_is_open) socket.setSoTimeout(0);or something like that?
# 7
Good grief. Of course not. How on earth do you think that could possibly relate to what I said: 'Use a read timeout on the read so it won't block forever; if you get a timeout and the socket is still open, loop.'
ejpa at 2007-7-10 13:06:39 >

# 8
I wrote that I don't understand you...Maybe, it is the best just to forget this post :)
# 9
Sigh. Set the timeout. Read in a loop. If you get data, break. If you get a timeout exception, continue looping if your socket is still open, otherwise break.Would you like the code too? Just tell me where to send the invoice.
ejpa at 2007-7-10 13:06:39 >

# 10
Now I understand - without timeout, I have that part of code.
I am author of chess on http://www.yupgames.com/playchess.asp. When user close explorer, his socket do not throw exception. It is problem. I even do not does jvm ever close it or what else. After some time I know if user is still logged or not, but if not, I can not just close the socket (I've described problem above). That's why I am looking for help...
# 11
If you are reading from a socket which has been closed by the other end you will get an EOF exception or null or -1 return value, depending on what read method you called, if the other end did a proper close. If it did an abortive close like IE does you will get nothing, which is why you need a timeout (you need a timeout on any serious network application anyway). If you write to such a socket you will get a SocketException or IOException: connect reset, after a certain amount of data has been written.
ejpa at 2007-7-10 13:06:39 >

# 12
I will set some amount of time to set.SoTimeout() - thank you :)
> If you write to such a
> socket you will get a SocketException or IOException:
> connect reset, after a certain amount of data has
> been written.
Does it can be cause to this post http://forum.java.sun.com/thread.jspa?threadID=5128234? I am making new socket each time new user arrives, but maybe I should do something more.
After each several seconds (5 sec) client is sending some junk message to server, which should tell that applet is still up. If I do not get message, I logout user (and was trying to close socket, but this problem did happen). Now I understand it is much better to use socket timeout, of course :)
# 13
You'd be better off looking at http://forum.java.sun.com/thread.jspa?threadID=748677
ejpa at 2007-7-10 13:06:39 >

# 14
Do you have some suggestion what I should do? Is there some way to expand socket's queue or proper closing sockets will solve the problem?
# 15
What problem? If you're setting a socket timeout etc you should have just solved the one you described first.
ejpa at 2007-7-21 19:21:09 >

# 16
Ok. I will write again if I get the same error. It happens after 4000 played matches, so I should wait :)
# 17
What error? All you've described so far is a lockup due to trying to close the socket in another thread, and the technique I've described should fix that.
ejpa at 2007-7-21 19:21:09 >

# 18
Sorry. I thought about another post, about connection reset "from somewhere". As I understood it is because queue with sockets becomes too large, but if I close socket, I hope it is same as I "call pop()".
# 19
None of that is true. 'Connection reset' has nothing to do with queues and there is no such operation as pop with sockets.
ejpa at 2007-7-21 19:21:09 >

# 20
Sometimes I am not enough "understandable", so I'll try again.
As I understood you, connection reset is error which becomes if socket's queue is full. When I wrote "I hope it is same as I "call pop()".", I didn't think that I can call pop. I thought, if I close socket, system (jvm or what ever) will remove, destroy, socket, so connection reset will not occur.
Now, simple question :)
If I always close socket, is there any way to get connection reset, actually, socket's queue becomes full?
P.S. There is always choice to try that, test and wait for another "fall down server" and then ask again :)
# 21
> As I understood you, connection reset is error which
> becomes if socket's queue is full.
You haven't understood me at all. You made that misconception up yourself, you didn't get it from me. As I just told you, it has nothing to do with queues.
'Connection reset' occurs when you write to a socket which is either already closed at the other end, or has been deliberately reset at the other end via a certain technique.
> If I always close socket, is there any way to get
> connection reset
See above. You can cause a connection reset at the other end if you close your socket before you've read all the data it is sending.
> actually, socket's queue becomes full?
For the third time, nothing to do with it.
ejpa at 2007-7-21 19:21:09 >

# 22
Now, finally :-|, I understand your replays.
What I should do, if I get connection reset, to keep accepting connections. This is what I am doing now (probably the most stupid "solution")
while (true){
try {
ServerSocket ss = new ServerSocket(TCP_PORT);
while (true) {
Socket sock = ss.accept();
in = new BufferedReader(
new InputStreamReader(
sock.getInputStream()));
out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
sock.getOutputStream())), true);
String msg = in.readLine();
tmpAddr = sock.getInetAddress().getHostAddress();
// here, I am making new client if parameters are good, else close the socket.
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
When I got "connection reset" last time, it was looping and writing exception for seven minutes, making file bigger than 50 MB, but I shouldn't reset server. Is there some way, when that error occur, to do something and again start accepting client connections?
Thank you.
# 23
I'm not sure these will work, but at least one of them ought to, so give 'em a try.
1. Put the try-catch inside the accept loop. It's possible the ServerSocket isn't closed(hence leaving the port open and unusable).
2. If the ServerSocket does become unusable, try closing it in the "catch" before creating a new one. Force-closing it, that is. Make sure it's really closed so that the port is reusable.
3. Catch specific exceptions. Try to tell apart a situation that would be fixed by looping from a situation caused by the looping. It's no wonder catching a general purpose "Exception" may cause the creating of a new ServerSocket to keep on failing. And if it failed once, as you continue to loop it just continues to fail, making the whole deal very counter-productive.
P.S. For the sake of your log file size, maybe you should accept a fatal error after a specific number of consecutive passes through that "catch" and at least avoid the stack dump, if not break out of the loop.
# 24
Getting a connection reset on a Socket won't do anything to the ServerSocket.
However you should never do I/O in the same thread as the accept() loop, or even create any streams. Just start the client thread and let it do all the rest. If the client thread gets an IOException of any kind, stop what it is doing, log the exception, close the output stream, and exit the thread.
ejpa at 2007-7-21 19:21:10 >

# 25
Thank you both for your help. I'll change that and test it. If I get some error with "accept socket loop" again, I'll ask for help.Have a nice day,