Java Forum / General / June 2005
Disconnect causing READ_OP?
Remon van Vliet - 14 Jun 2005 13:39 GMT Hello,
I was wondering, when a client closes a socket connection to a NIO based server, is an active attempt to read from that channel the only way to detect a disconnect or should a READ_OP key be selected at some point without the active attempt to read?
Regards,
Remon
Esmond Pitt - 15 Jun 2005 02:33 GMT > Hello, > > I was wondering, when a client closes a socket connection to a NIO based > server, is an active attempt to read from that channel the only way to > detect a disconnect or should a READ_OP key be selected at some point > without the active attempt to read? Right both times actually. The disconnect will cause OP_READ to become ready, but the only way you can distinguish EOF from data when this happens is to try the read.
Remon van Vliet - 15 Jun 2005 09:18 GMT > > Hello, > > [quoted text clipped - 6 lines] > ready, but the only way you can distinguish EOF from data when this > happens is to try the read. Okay i figured this should be the cause, for some reason if i do a SocketChannel.close() on the client end a READ_OP is not selected for the related key on the server end. I'll recheck some things. Thanks for your input.
iksrazal@terra.com.br - 15 Jun 2005 17:11 GMT Carefully read the JavaDocs, as you may find you also need to do...
Socket socket = channel.socket(); socket.shutdownOutput(); socket.shutdownInput(); socket.close(); channel.close(); channel = null; socket = null;
Or something like that.
HTH, iksrazal http://www.braziloutsource.com/
Remon van Vliet - 16 Jun 2005 12:57 GMT Very useful reply thanks, apparently, a neat disconnect occurs once the socket object is nulled (and thus garbage collected/destroyed), and not when it's close() method is called. Does anyone know the logic behind this?
Remon
> Carefully read the JavaDocs, as you may find you also need to do... > [quoted text clipped - 11 lines] > iksrazal > http://www.braziloutsource.com/ Remon van Vliet - 16 Jun 2005 12:59 GMT Ah, never mind, made a slight error in my test code, it's shutdownInput()/output() that does it. Thanks nevertheless.
Remon
> Very useful reply thanks, apparently, a neat disconnect occurs once the > socket object is nulled (and thus garbage collected/destroyed), and not when [quoted text clipped - 17 lines] > > iksrazal > > http://www.braziloutsource.com/ Esmond Pitt - 16 Jun 2005 13:55 GMT > Carefully read the JavaDocs, as you may find you also need to do... > [quoted text clipped - 7 lines] > > Or something like that. Or something like something, or whatever. Keep taking the pills.
Actually any one of channel.close() or socket.close() is enough. You don't need the nulling, and you don't need the shutdowns either if they are followed immediately by a close. If you really do read the Javadocs properly you will see that if the channel has been registered with a Selector, the socket won't get properly closed (from the netstat -a point of view) until the next select() call. In clients with only one channel this means that channel.close() should be followed by selector.selectNow().
iksrazal@terra.com.br - 16 Jun 2005 16:30 GMT I passed the pills to you but you never gave them back! I appreciate your comments and over time they have added to my knowledge. In this particular case I proved that indeed socket.close() and channel.close() were not enough - I had the open file descriptors to prove it when it happened. The nulls may not be absolutely neccesary but that wasn't the point - which is that NIO does not abstract you %100 from the original Socket class. The OP also claims the calls indeed solved his problem and apparently benefitted from the advice - which is the purpose of this group. You may have an alternative method but that doesn't discount that there is more than one way to solve the problem.
Specifically per you advice, I don't see how the SocketChannels could be cached and re-used on the client side by enforcing a selectNow() rule for the Selector. Furthermore, I'm not sure if you generally assume a NIO Socket implementation on the server-side - of course that is not always the case.
Take a chill pill yourself, do us all a favor and explain - by reading the javdocs which I did a couple hundred times while chasing down this problem when it occurred - what the exact reason why the Channel class supplies a hook the the Socket class.
And give me my pills back ;-) .
Cheers, iksrazal
Remon van Vliet - 16 Jun 2005 16:32 GMT Agreed, just a .close() is NOT enough, nulling doesnt help either way though, but the manual shutdown methods are a must to generate a proper OP_READ with -1 on the other side.
> I passed the pills to you but you never gave them back! I appreciate > your comments and over time they have added to my knowledge. In this [quoted text clipped - 22 lines] > Cheers, > iksrazal Bjorn Borud - 17 Jun 2005 01:00 GMT ["Remon van Vliet" <remon@exmachina.nl>]
| Agreed, just a .close() is NOT enough, nulling doesnt help either way | though, but the manual shutdown methods are a must to generate a proper | OP_READ with -1 on the other side. how do you explain this?
-Bjørn
Esmond Pitt - 17 Jun 2005 10:31 GMT > I passed the pills to you but you never gave them back! I've been taking them but I've forgotten what they're for!!
> I appreciate > your comments and over time they have added to my knowledge. In this > particular case I proved that indeed socket.close() and channel.close() > were not enough - I had the open file descriptors to prove it when it > happened. So if both closes aren't sufficient, what evidence is there that both are necessary?
> The nulls may not be absolutely neccesary The nulls aren't necessary at all, absolutely or otherwise.
> but that wasn't the > point - which is that NIO does not abstract you %100 from the original > Socket class. I agree and so does the Javadoc: 'Socket channels are not a complete abstraction of connecting network sockets'. So?
> The OP also claims the calls indeed solved his problem > and apparently benefitted from the advice - which is the purpose of > this group. You may have an alternative method but that doesn't > discount that there is more than one way to solve the problem. Shutting down the JVM would also solve the OP's problem, but that doesn't make it the right answer. You don't have to use a shotgun where a .22 would do, and you don't need 5 lines of mostly redundant code where one correct line addressed at the issue would do.
You can remove the channel.socket().close() and your code will still work. You can then remove the channel.socket().shutdownInput() and your code will still work. You can then remove the nulling and your code will *still* work. Isn't this relevant?
selectNow() will *also* work and this solution is related to the underlying reason for the issue, which is that registering with a Selector causes the close to be deferred until the next select() operation, as it does say somewhere in the Javadoc which I can never find when I need it.
> Specifically per you advice, I don't see how the SocketChannels could > be cached and re-used on the client side by enforcing a selectNow() > rule for the Selector. That's not what I said and frankly I don't know what you're talking about here.
Furthermore, I'm not sure if you generally
> assume a NIO Socket implementation on the server-side - of course that > is not always the case. There is no way that what is at the other end of a TCP/IP connection can determine what the correct technique is at this end, as long as the other end is correctly implemented. Again I don't know what is being talked about here.
> Take a chill pill yourself, do us all a favor and explain - by reading > the javdocs which I did a couple hundred times while chasing down this > problem when it occurred - what the exact reason why the Channel class > supplies a hook the the Socket class. Well, this is easy but irrelevant. The exact reason is obviously so that SocketChannel does not have to provide yet another interface for the Socket methods get/setSend/ReceiveBufferSize, get/setSoTimeout, get/setTcpNoDelay, shutdownInput/Output, ...
Perhaps can you tell us what SocketChannel.close is supposed to do if not close the socket?
Perhaps you could also try some of the experiments suggested above and report? I have.
iksrazal@terra.com.br - 17 Jun 2005 13:37 GMT > > I passed the pills to you but you never gave them back! > > I've been taking them but I've forgotten what they're for!! Good stuff man.
> > I appreciate > > your comments and over time they have added to my knowledge. In this [quoted text clipped - 4 lines] > So if both closes aren't sufficient, what evidence is there that both > are necessary? It doesn't work. What more do you want? The server keeps the connection open, the client can't close it using Socket.close() or SocketChannel.close(). Esmond, the jist of your comment is looking for perfection. Yet when you have a socket that is not closing, it can be a frustrating problem and you want a solution. That is what I provided.
The OP will have to provide evidence - I'm at another company now and I was connecting to a mainframe when the problem occurred. I'm open to trying to duplicate the problem in another way if the OP can't help. However...
http://bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=6215050
May explain the problem.
> > The nulls may not be absolutely neccesary > > The nulls aren't necessary at all, absolutely or otherwise. Moving on...
> > but that wasn't the > > point - which is that NIO does not abstract you %100 from the original > > Socket class. > > I agree and so does the Javadoc: 'Socket channels are not a complete > abstraction of connecting network sockets'. So? So, its a _big_ suprise to many people. The OP didn't know it, and I bet half the people using NIO don't know that. You can't expect everyone to be an NIO expert, or to read the javadoc and remember sublities on every class they use.
> > The OP also claims the calls indeed solved his problem > > and apparently benefitted from the advice - which is the purpose of [quoted text clipped - 5 lines] > a .22 would do, and you don't need 5 lines of mostly redundant code > where one correct line addressed at the issue would do. Big difference - the problem is solved _and_ the program continues to run. Take away the nulls - now its 3 lines extra.
You're shotgun analogy brings up an important point - profiling. What documented proof - not just speculation and wild analogies - do you have of an important performance difference between shutdownInput() and selectNow()?
> You can remove the channel.socket().close() and your code will still > work. You can then remove the channel.socket().shutdownInput() and your > code will still work. You can then remove the nulling and your code will > *still* work. Isn't this relevant? I left those in for the OP to try out for himself. IIRC, it was shutdownInput() that closes the socket via -1. Again, without it, no worky.
> selectNow() will *also* work and this solution is related to the > underlying reason for the issue, which is that registering with a > Selector causes the close to be deferred until the next select() > operation, as it does say somewhere in the Javadoc which I can never > find when I need it. shutdownInput() is as clear as day, works fine, and until I see profiling proof otherwise, I will continue to recommend it.
> > Specifically per you advice, I don't see how the SocketChannels could > > be cached and re-used on the client side by enforcing a selectNow() > > rule for the Selector. > > That's not what I said and frankly I don't know what you're talking > about here. Say I have a client side method...
public static String readFromChannel (SocketChannel sChannel, final int size, Pattern pattern) throws IOException
In this methods finally block I could add a selectNow(). However, in this case socket channels are cached in a Map protected by semaphores - the sockets are very expensive to create via authentication and the protocol just sends and returns Strings. I stop the read on a Pattern. A timer task is responsible for the shutdown of the cache for periodic refresh. I use shutdownInput() close the socket, as I don't want to close the socket in this method.
See this explanation on selectNow() .
http://bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=6215050
The recomendation is that selectNow() needs to be placed everywhere the SocketChannel is used. I haven't used selectNow() - though I will give it a look when I get a chance. I do think that shutdownInput() in one place as opposed to selectNow() everywhere would produce less lines of code in certain situations.
> Furthermore, I'm not sure if you generally > > assume a NIO Socket implementation on the server-side - of course that [quoted text clipped - 14 lines] > Socket methods get/setSend/ReceiveBufferSize, get/setSoTimeout, > get/setTcpNoDelay, shutdownInput/Output, ... Yep, exactly - not irrelevant at all. NIO provides a hook that will close the socket via Socket.shutDownInput(). It works fine, trust me. Profile it vs selectNow(), look at the bugs referenced at sun's bugdatabase, and for the benefit of the group let us know what you think.
> Perhaps can you tell us what SocketChannel.close is supposed to do if > not close the socket? > > Perhaps you could also try some of the experiments suggested above and > report? I have. I use linux with the JVM listed in the bug db and personally seen the file descriptor leak.
"4. When the server side closes the socket sometime AFTER the first read returns."
See the sample TestClose for an example. The close doesn't work.
I look forward to testing selectNow() when I get a chance.
iksrazal
Esmond Pitt - 18 Jun 2005 09:56 GMT > http://bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=6215050 > > May explain the problem. It does. It says you have to call selectNow().
> Big difference - the problem is solved _and_ the program continues to > run. Take away the nulls - now its 3 lines extra. No, the problem is *not* solved, because the socket is *still* open, *until* you do selectNow(). Try it. Calling shutdownOutput() causes the peer to get an EOF, which is nice, but netstat -a will still show the local socket as ESTABLISHED and eventually the local JVM will run out of file descriptors (again, try it), unless it calls selectNow(). There is a long thread on this in the Java Forums/Socket Programming entitled 'taming the NIO circus' which I recommend you also read.
> Your shotgun analogy brings up an important point - profiling. What > documented proof - not just speculation and wild analogies - do you > have of an important performance difference between shutdownInput() and > selectNow()? I am not speculating; wild analogies are in the eye of the beholder. I said nothing about 'an important performance difference', this is just another invention--it's a *functionality* difference: otherwise see the forum thread cited above.
Socket.shutdownInput() sends nothing on the wire and has no effect on the local protocol stack except to cause it to return EOF on local reads and depending on what platform you are on to either (i) ignore (ii) reset or (iii) acknowledge any further data sent by the peer. This is not speculation it is fact.
selectNow() on the other hand implements the deferred part of the socket close which causes (i) a FIN to be sent if not already sent, (ii) the socket to be put out of ESTABLISHED state into FIN_WAIT_1 state &c and (iii) cause it to return EOF on local reads and (iv) cause further data sent by the peer to be replied to with an RST.
This also fact not speculation.
> I left those in for the OP to try out for himself. IIRC, it was > shutdownInput() that closes the socket via -1. Again, without it, no > worky. > shutdownInput() is as clear as day, works fine, and until I see > profiling proof otherwise, I will continue to recommend it. I'm sorry but this is rubbish. (a) shutdownInput() definitely and absolutely does not close the socket: see above and any reputable TCP/IP book such as Stevens. (b) If it does close the socket, why do you need the other two closes? Please. Let's try to be logical about this.
> In this methods finally block I could add a selectNow(). However, in > this case socket channels are cached in a Map protected by semaphores - I do not understand this business of maps and semaphores at all, is this anothe red herring?
> http://bugs.sun.com/bugdatabase/view_bug.do;:YfiG?bug_id=6215050 This *and* the other bug you cited *and* all the bugs they are cross-referenced to agree that selectNow() is the solution. What else do you need? *Not one* of these bugs describes shutdownInput() as an alternative solution.
> The recomendation is that selectNow() needs to be placed everywhere the > SocketChannel is used. I haven't used selectNow() - though I will give > it a look when I get a chance. In other words you are still guessing. I am *not* guessing, and all the references cited above agree with me.
Let me know about the pills, they are now working for me.
Best
EJP
iksrazal@terra.com.br - 18 Jun 2005 13:37 GMT > In other words you are still guessing. I am *not* guessing, and all the > references cited above agree with me. I'm not guessing anymore. I proved it to myself a while back, another poster also acknowledged that shutdown calls work, and now I took a saturday morning off to prove my point. You fail to acknowledge that the shutdown() calls can work and demonstratably Channel.close() sometimes does not. I believe the shutdown() calls are clearer - certainly from a JavaDoc standpoint that is true. Regardless, here's the proof.
The code below is taken from the bug report link above - I only changed the package and one print statement after my code in the finally block. My system is Suse Pro 9.2 Linux, using the default jvm /usr/lib/jvm/java-1.4.2-sun-1.4.2.05 . The default smtp server is postfix, which by default only accepts connections from localhost.
Conclusions:
- Channel.close() does not work aa the bug report stated - shutdownOutput() works just fine ;-) , ie via 'netstat -an | grep CLOSE_WAIT' - without socket.close() , isConnected() return true always, with socket.close() about half the time the code returns false, but as Gordon eloquently once said:
- isConnected() and isInputShutdown() cannot be relied upon to say anything meaningful about the state of the actual connection.
I put some simple System.currentTimeMillis() in to profile - care to take the pepsi challege with selectNow() ?
> Let me know about the pills, they are now working for me. > > Best > > EJP Don't bogart - I mean it is good stuff man ;-).
Best likewise, iksrazal
package com.whitezone;
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.net.Socket; import java.nio.channels.SocketChannel; import java.util.StringTokenizer;
// Test case code for file descriptor leak. // The following should produce somewhere near 150 sockets in CLOSE_WAIT state. // // The problem appears to be in sun.nio.ch.SocketAdapter.SocketInputStream.read(ByteBuffer); //
public class TestClose implements Runnable {
public static final String SMTP_HOSTNAME = "localhost";
public void run() { InetSocketAddress sockAddr = new InetSocketAddress(SMTP_HOSTNAME, 25); SocketChannel sChannel = null; Socket socket = null; try { sChannel = SocketChannel.open(); sChannel.connect(sockAddr);
// I've noticed that if I remove this line the problem no longer happens sChannel.socket().setSoTimeout(5000);
socket = sChannel.socket();
BufferedReader lineRdr = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String result = null; do { // before performing the first readline the channel is unregistered System.err.println("before first readline: isOpen = "+sChannel.isOpen()+" isRegistered="+sChannel.isRegistered());
result = lineRdr.readLine(); System.err.println("<- "+result);
// after performing it is registered. System.err.println("after first readline: isOpen = "+sChannel.isOpen()+" isRegistered="+sChannel.isRegistered());
} while(result != null && result.length() > 0 && result.matches("^[1-5][0-9]{2}-"));
if(result == null || result.length() == 0) { System.err.println("Received truncated response from SMTP server " + sockAddr.getHostName()); return; }
// Tokenize the last line result // StringTokenizer t = new StringTokenizer(result); int rc = Integer.parseInt(t.nextToken()); if(rc != 220) return;
// // Send the QUIT command causing the server side to close its end of the connection // String cmd = "QUIT\r\n"; socket.getOutputStream().write(cmd.getBytes()); System.err.println("-> "+cmd); do { result = lineRdr.readLine(); System.err.println("<- "+result); } while(result != null && result.length() > 0 && result.matches("^[1-5][0-9]{2}-"));
if(result == null || result.length() == 0) { System.err.println("Received truncated response from SMTP server " + sockAddr.getHostName()); return; }
} catch (Exception e) { e.printStackTrace(); } finally { try {
System.err.println("before close: isOpen = "+sChannel.isOpen()+" isRegistered="+sChannel.isRegistered());
System.err.println("Closing SMTP socket channel "+sChannel); System.err.println("channel.socket().isConnected = "+ sChannel.socket().isConnected()); if (sChannel != null) { //sChannel.close(); long start = System.currentTimeMillis(); System.currentTimeMillis(); Socket socket_close = sChannel.socket(); // by socket_close.shutdownOutput() itself, CLOSE_WAIT issue fixed socket_close.shutdownOutput(); // with socket_close.close() , isConnected returns false sometimes socket_close.close(); long end = System.currentTimeMillis(); System.err.println("Closed SMTP socket channel "+sChannel+", Execution time was "+(end-start)+" ms.");
// The socket is still connected here. System.err.println("\n\nAFTER shutdownOutput channel.socket().isConnected = "+sChannel.socket().isConnected()); } } catch (Exception e) { System.err.println("Exception on close:"); e.printStackTrace(); } }
return; }
public static void main(String[] args) { TestClose test = new TestClose(); for(int i = 0; i < 150; i++) { // this bug seems only to appear if different threads are reading the channels Thread thread = new Thread(test); thread.start(); try {thread.join(); } catch(InterruptedException e) { } }
System.err.println("Going to sleep.... run netstat -an | grep CLOSE_WAIT "); while(true) { try { Thread.sleep(10000); } catch(InterruptedException e) {} } } }
Esmond Pitt - 20 Jun 2005 05:02 GMT OK so which is it?
You are telling us that channel.close() doesn't work, although it works well enough for you to leave it there; you have added channel.socket().close() which you seem to think also doesn't work but you are leaving it there, when a quick look at the source code would tell you that channel.socket().close() just calls channel.close(); you have added channel.socket().shutdownOutput() which does change the socket to CLOSE_WAIT, I agree, and you are leaving that there; you have also added shutdownInput() which you said a few messages ago does actually close the socket, which is not correct as you now agree, and you have also left that there; and you have also nulled out the channel and socket references, which does nothing, which you have also left there.
Meanwhile you still have your 'file descriptor leak', or 150 sockets in CLOSE_WAIT, or whatever you want to call it, and meanwhile you *still* haven't tried this:
channel.close(); selector.selectNow();
Meanwhile let me risk Sun's wrath and quote a comment from the source code of implCloseSelectableChannel():
// If this channel is not registered then it's safe to close the fd // immediately since we know at this point that no thread is // blocked in an I/O operation upon the channel and, since the // channel is marked closed, no thread will start another such // operation. If this channel is registered then we don't close // the fd since it might be in use by a selector. In that case // closing this channel caused its keys to be cancelled, so the // last selector to deregister a key for this channel will invoke // kill() to close the fd.
(where kill() is the thing that really closes the file descriptor), and finally let me assure you that the code which follows implements the comment correctly.
Your 'bug report' only exposes a misunderstanding of what isConnected() is supposed to do: it is supposed to return false before you have called socket.connect() and true afterwards, and it does. It has nothing to do with the state of the connection or with what the other end may or may not have done.
iksrazal@terra.com.br - 20 Jun 2005 13:43 GMT You've lost me - quite an extremely overactive imagination you've got there. Must be the pills. You mix your fetish like fascination with low-level protocols, with a blatant mis-representaion of my last post to delusional proportions.
So push has come to shove...
> OK so which is it? > > You are telling us that channel.close() doesn't work, although it works > well enough for you to leave it there; Wrong. I commmented it out:
//sChannel.close();
> you have added > channel.socket().close() which you seem to think also doesn't work but > you are leaving it there, when a quick look at the source code would > tell you that channel.socket().close() just calls channel.close(); You have this strange need to write and read your own words when it serves no purpose. What is it about what I wrote:
// with socket_close.close() , isConnected returns false sometimes
and
- isConnected() and isInputShutdown() cannot be relied upon to say anything meaningful about the state of the actual connection.
That you don't you understand?
> you > have added channel.socket().shutdownOutput() which does change the > socket to CLOSE_WAIT, I agree, and you are leaving that there; Wrong again. Try running the code. That is not what happens. Putting a sleep _before_ shutDownOutput() you will see:
/root> netstat -an | grep CLOSE_WAIT tcp 0 0 127.0.0.1:1650 127.0.0.1:25 CLOSE_WAIT
_after_ shutDownOutput() you will see no grep output for CLOSE_WAIT . Which is what the bug report says is the issue, and what shutDownOutput() fixes.
You said:
"Calling shutdownOutput() causes the peer to get an EOF, which is nice, but netstat -a will still show the local socket as ESTABLISHED and eventually the local JVM will run out of file descriptors (again, try it), unless it calls selectNow(). "
I call bullshit here. Try running the code.
You see, your references to a 10 year old book by some dead white guy doesn't impress me. Specs lie, docs lie. I'm a nihilist - the only thing I believe in is neil young. That and running code, sniffers, netstat and profilers. Without those, you're just another guy on usenet.
> you have > also added shutdownInput() which you said a few messages ago does > actually close the socket, which is not correct as you now agree, and > you have also left that there; Wrong again. No shutdownInput() in the code. I qualified shutdownInput() with 'IIRC'.
> and you have also nulled out the channel > and socket references, which does nothing, which you have also left there. Wrong again. Unless you are refering to the declaration of the variables by the original coder.
> Meanwhile you still have your 'file descriptor leak', or 150 sockets in > CLOSE_WAIT, or whatever you want to call it, and meanwhile you *still* > haven't tried this: > > channel.close(); > selector.selectNow(); You seem awfully liberal of my time, of which I've given plenty by running the code from the bug report and fixing it as I claim, the best I can, via running it and posting it here. I _CLAIM_ the code I've submitted _fixes_ the issue raised in bug report - as I previously stated fixed an issue for me and helped the OP out. Try running the code and _prove_ me wrong. Only running code can do that, not because some guy on usenet claims otherwise.
Speaking of time, how about giving yours and submitting _runnable_, _tested_ code that fixes the code from the bug report via selectNow() . I dare you. Put up or shut up. I also dare you to run the posted code and tell me exactly what it does.
> Meanwhile let me risk Sun's wrath and quote a comment from the source > code of implCloseSelectableChannel(): [quoted text clipped - 12 lines] > finally let me assure you that the code which follows implements the > comment correctly. Only factual part of your reply.
> Your 'bug report' only exposes a misunderstanding of what isConnected() > is supposed to do: it is supposed to return false before you have called > socket.connect() and true afterwards, and it does. It has nothing to do > with the state of the connection or with what the other end may or may > not have done. Again, writing your own words because you like to read them. I already stated that.
Keep the pills. Reality is for people who can't handle drugs. iksrazal
Esmond Pitt - 22 Jun 2005 04:25 GMT [snip]
OK, I give up. Good luck with your futile bug report, whatever it's about.
iksrazal@terra.com.br - 22 Jun 2005 11:59 GMT > [snip] > > OK, I give up. Good luck with your futile bug report, whatever it's about. Rehab is for quitters you know. And it is not futile - people in the real world have problems to solve - not just abundant time to pyscho-analyze JDK source comments in their mothers basement. See yet another bug report - this time with shutdown*() calls as the 'workaround' :
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4726957
Furthermore, these bugs are _acknowledged_ by Sun themselves.
So in the end, you were wrong where it mattered, and right where it did not. Needlessly criticizing and being condescending from the start is like pounding on the table - it does not make you right. Combining that by saying that everyone is this thread and the bug reports are wrong, shows you have stopped being an engineer and are now simply just one helluva an a.shole.
My suggestion is to stop your mental masturbation gymnastics on NIO, open the door on a sunny day and go out and meet a girl. Avoid talking about the nuances of the kill() method and you may even kiss one somday.
iksrazal
Esmond Pitt - 23 Jun 2005 11:50 GMT [yards of offensive & irrelevant matter snipped]
Sigh. Ignoring, with great difficulty, 98% of your message which consists of an ad hominem attack on me, I will deal with the ever-decreasing factual content, for the last time.
Socket.shutdownInput() does not close the socket, contrary to what you said about a hundred messages ago, and Socket.shutdownOutput() doesn't either, although it can give the other end the impression that it has. The only two APIs that close the socket from the OS point of view are Socket.close(), or SocketChannel.close() which is equivalent: if the channel is registered this cycle must be completed by Selector.selectXXX() for all the selectors concerned. There was a bug in this area concerning blocking socket channels with timeouts which is now closed, and there were lots of Channel I/O/select bugs in the early releases of JDK 1.4 which AFAIK are also now closed (although I certainly do not claim that NIO is error-free).
I'm sorry if you can't understand that, or if you think that ad hominem attacks on me constitute debate, but I can't follow you down any of those paths. The 'yet another bug report' you cite is a duplicate, was closed by Sun in 2002, and does not bear on any of the issues you have raised. Neither do any of the related bugs, which are also closed. None of them supports your contention.
It is curious that you are prepared to regard Sun, the author of these bugs, as an authority, but not the TCP/IP RFC or W.R. Stevens who is indeed dead and white and male, but who knew more about it that either you or I. I'm not so concerned with your own misunderstandings, as you evidently know very little about TCP/IP and even less about rational problem solving (profiling constitutes debugging?), but I don't like to see misinformation spread on the newsgroups to mislead others.
I am just trying to correct an error which you perpetrated, but I would agree that at this point I have lost track of what you are now actually trying to prove. The appearances are that you have too.
baci
EJP
> See yet > another bug report - this time with shutdown*() calls as the > 'workaround' : > > http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4726957
> Furthermore, these bugs are _acknowledged_ by Sun themselves. Described as fixed about three years ago ...
> So in the end, you were wrong where it mattered, and right where it did > not. Needlessly criticizing and being condescending from the start is > like pounding on the table - it does not make you right. Combining that > by saying that everyone is this thread and the bug reports are wrong, > shows you have stopped being an engineer and are now simply just one > helluva an a.shole. More of your rational method of enquiry?
> My suggestion is [snip]
At this point I am sorry to say that I have entirely lost track of what it is you are trying to say, but if you think that shutdownInput() or shutdownOutput() closes the socket your are still mistaken.
Remon van Vliet - 23 Jun 2005 11:58 GMT > [yards of offensive & irrelevant matter snipped] > > Sigh. Ignoring, with great difficulty, 98% of your message which > consists of an ad hominem attack on me, I will deal with the > ever-decreasing factual content, for the last time. Isnt that the truth.
> Socket.shutdownInput() does not close the socket, contrary to what you > said about a hundred messages ago, and Socket.shutdownOutput() doesn't [quoted text clipped - 7 lines] > releases of JDK 1.4 which AFAIK are also now closed (although I > certainly do not claim that NIO is error-free). True, however, i did find that using Socket.close() or SocketChannel.close() did not cause my server to see a new OP_READ, the shutdown methods did. As opposed to the person you're argueing with i do consider this a workaround though.
iksrazal@terra.com.br - 23 Jun 2005 21:19 GMT Low signal to noise for sure. It is a workaround - no doubt about it. SocketChannel.close() should by itself do the job.
iksrazal
iksrazal@terra.com.br - 23 Jun 2005 18:33 GMT > [yards of offensive & irrelevant matter snipped] > > Sigh. Ignoring, with great difficulty, 98% of your message which > consists of an ad hominem attack on me, I will deal with the > ever-decreasing factual content, for the last time. Sigh likewise. This will also be my last post as you just continue to provably mis-represent my previous posts. And lets not forget that the "ad hominem attack" started with your comment:
"Keep taking the pills."
Play with fire, burn your fingers.
> Socket.shutdownInput() does not close the socket, contrary to what you > said about a hundred messages ago, and Socket.shutdownOutput() doesn't > either, For the second time I will say I qualified Socket.shutdownInput() with 'IIRC' . I note that the last bug report leaves Socket.shutdownInput() in the 'if(workAround) ' .
> although it can give the other end the impression that it has. The local connection going from CLOSE_WAIT to TIME_WAIT is no impression but a simple fact shown by running code via the shutdownOutput() method. And of course it has nothing to do with the other end as in that case the server side is completely closed. There probably are other situations regarding close() but that is demonstrated in the test case I suppled which you responed to with mere speculation.
Even still, if you admitted that posibility in the beginning - which I stated I personally seen from my first post and took time to prove - it would have saved a lot of time and could have avoided bad feelings. Others have seen the same thing.
> The only two APIs that close the socket from the OS point of view are > Socket.close(), or SocketChannel.close() which is equivalent: if the [quoted text clipped - 4 lines] > releases of JDK 1.4 which AFAIK are also now closed (although I > certainly do not claim that NIO is error-free). So the bug reports were not futile? "must be completed by Selector.selectXXX()" is pure moonshine.
> I'm sorry if you can't understand that, or if you think that ad hominem > attacks on me constitute debate, but I can't follow you down any of > those paths. The 'yet another bug report' you cite is a duplicate, was > closed by Sun in 2002, and does not bear on any of the issues you have > raised. Neither do any of the related bugs, which are also closed. None > of them supports your contention. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4726957
"This is still reproducible with java 1.5.0beta2"
"CUSTOMER WORKAROUND : -use Socket.shutdownOutput() and shutdownInput() instead of close(). The former results in a FIN segment. -use "new Socket(..)" instead of SocketChannel.open(..) if non-blocking IO is not needed -don't use setSoTimeout() if not needed (Review ID: 160421) "
Perhaps your pounding on the table works elsewhere - you seem to try it a lot.
> It is curious that you are prepared to regard Sun, the author of these > bugs, as an authority, but not the TCP/IP RFC or W.R. Stevens who is [quoted text clipped - 3 lines] > problem solving (profiling constitutes debugging?), but I don't like to > see misinformation spread on the newsgroups to mislead others. Pure mis-representation and confirms your condescending fallback approach when the facts are clearly against you.
Concerning profiling, a mere look at my posts irrefutably show I was curious if there was a non-trivial performance difference between selectNow() and shutdownOutput() , and in general is what I rely on before changing code and blindly assumming a performace boost. As stated I believe profilers before specs.
Concerning TCP, you shouldn't need to know a lot at the API level of Java. Nevertheless and at the risk of every syllable I write being analysed and needlessly attacked, the CLOSE_WAIT state can be caused by at least two methods; The first being far more common and is what I have seen:
a) The remote side has closed the connection, but the local socket is still open. b) remote side has called shutdown(SHUT_WR). This would make the TCP connection unidirectional, from the local to the remote side.
The SocketChannel.close() method provably does not change the state of CLOSE_WAIT up until at least v1.4.2 when used with setSoTimeout().
A call to shutdownOutput() performs a final read() to the filedescriptor of the port and clears CLOSE_WAIT.
> I am just trying to correct an error which you perpetrated, but I would > agree that at this point I have lost track of what you are now actually > trying to prove. The appearances are that you have too. The whole thing got started when I tried to help someone out by pointing out the shutdown*() calls, who thanked me as it worked for him. You've been as rude as you are wrong ever since. Goodbye.
iksrazal
iksrazal@terra.com.br - 22 Jun 2005 12:05 GMT > [snip] > > OK, I give up. Good luck with your futile bug report, whatever it's about. Rehab is for quitters you know. And it is not futile - people in the real world have problems to solve - not just abundant time to pyscho-analyze JDK source comments in their mothers basement. See yet another bug report - this time with shutdown*() calls as the 'workaround' :
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4726957
Furthermore, these bugs are _acknowledged_ by Sun themselves.
So in the end, you were wrong where it mattered, and right where it did not. Needlessly criticizing and being condescending from the start is like pounding on the table - it does not make you right. Combining that by saying that everyone is this thread and the bug reports are wrong, shows you have stopped being an engineer and are now simply just one helluva an a.shole.
My suggestion is to stop your mental masturbation gymnastics on NIO, open the door on a sunny day and go out and meet a girl. Avoid talking about the nuances of the kill() method and you may even kiss one somday.
"The greatest enemy of knowledge is not ignorance, it is the illusion of knowledge." Stephen Hawking
iksrazal
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|