Disconnect causing READ_OP?

R

Remon van Vliet

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
 
E

Esmond Pitt

Remon said:
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.
 
R

Remon van Vliet

Esmond Pitt said:
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.

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

iksrazal

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/
 
R

Remon van Vliet

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
 
R

Remon van Vliet

Ah, never mind, made a slight error in my test code, it's
shutdownInput()/output() that does it. Thanks nevertheless.

Remon
 
E

Esmond Pitt

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.

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().
 
I

iksrazal

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
 
R

Remon van Vliet

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

Bjorn Borud

["Remon van Vliet" <[email protected]>]
| 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
 
E

Esmond Pitt

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

iksrazal

Esmond Pitt escreveu:
I've been taking them but I've forgotten what they're for!!

Good stuff man.
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 aren't necessary at all, absolutely or otherwise.

Moving on...
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.
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.

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

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.


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

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
 
E

Esmond Pitt


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?

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
 
I

iksrazal

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) {}
}
}
}
 
E

Esmond Pitt

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

iksrazal

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

Esmond Pitt escreveu:
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():

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

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
 
E

Esmond Pitt

(e-mail address removed) wrote:

[snip]

OK, I give up. Good luck with your futile bug report, whatever it's about.
 
I

iksrazal

Esmond Pitt escreveu:
(e-mail address removed) wrote:

[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 asshole.

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
 
I

iksrazal

Esmond Pitt escreveu:
(e-mail address removed) wrote:

[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 asshole.

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
 
E

Esmond Pitt

(e-mail address removed) wrote:
[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 asshole.

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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top