Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / June 2005

Tip: Looking for answers? Try searching our database.

Disconnect causing READ_OP?

Thread view: 
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 Magazines

Get 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 ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.