
Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/
Hi Thomas,
>> The problem I'm having is that when a client sends a query then later
>> goes away, I'm not always able to detect the situation to cancel their
[quoted text clipped - 11 lines]
> @since 1.4, Socket has gained a few methods which you could poll. For
> instance isOutputShutdown. I assume that does the obvious.
Thanks, I hadn't seen those methods. The problem is that the input
doesn't always come from a socket. My JUnit tests use pipes to test
parts of the system, and I'd like to keep that working if at all
possible. It doesn't look like PipedReader/PipedWriter implement
anything like isOutputShutdown; is there a way to convert them into
something that does?
I also don't see a way to create a non-Internet socket (like a Unix
domain socket, or a socketpair()-style socket) for testing. I guess I
could rig my test infrastructure up to use Internet sockets to
localhost, but that seems silly.
> Presumably NIO wouldn't be too bad. Use Socket.getChannel, and
> register that with a selector.
I haven't been able to figure out how to store an object that may be a
Socket or may be a Pipe with NIO. It looks like I can declare it as a
SelectableChannel, but that doesn't provide read or write methods; or
I can declare it as a Readable/WritableByteChannel, but that's not
selectable. Any ideas?
>> I've tried using BufferedReader.ready() and BufferedReader.read(new
>> char[1], 0, 0), but neither indicates whether I've reached EOF. If I
[quoted text clipped - 9 lines]
> hangs, Ctrl-\ (or Ctrl-Break on Windows) from the console should show
> what the problem is.
I tried; if I had a thread blocking on a read on the socket, then
writes to that socket blocked. When I don't create a reader thread,
everything works correctly. If that's not expected behavior, I can
probably put together a small test case to show the problem.
Thanks!
---Scott.
Thomas Hawtin - 04 Nov 2005 07:59 GMT
> Thanks, I hadn't seen those methods. The problem is that the input
> doesn't always come from a socket. My JUnit tests use pipes to test
> parts of the system, and I'd like to keep that working if at all
> possible. It doesn't look like PipedReader/PipedWriter implement
> anything like isOutputShutdown; is there a way to convert them into
> something that does?
You can always provide your own abstractions, but as this is just for
testing, we can note that Socket is not final...
> I also don't see a way to create a non-Internet socket (like a Unix
> domain socket, or a socketpair()-style socket) for testing. I guess I
> could rig my test infrastructure up to use Internet sockets to
> localhost, but that seems silly.
I don't think it's that silly.
> I haven't been able to figure out how to store an object that may be a
> Socket or may be a Pipe with NIO. It looks like I can declare it as a
> SelectableChannel, but that doesn't provide read or write methods; or
> I can declare it as a Readable/WritableByteChannel, but that's not
> selectable. Any ideas?
Without an extra layer, you would need to get into the details of the
SPI, which wouldn't be fun. Or use a mocking tool.
> I tried; if I had a thread blocking on a read on the socket, then
> writes to that socket blocked. When I don't create a reader thread,
> everything works correctly. If that's not expected behavior, I can
> probably put together a small test case to show the problem.
Within Socket.socketWrite0 (or PlainSocketImpl.acquireFD)? Where and
what are both threads blocked on. It shouldn't behave like that. Here's
a little test program.
import java.io.*;
import java.net.*;
class SimpleServer {
public static void main(String[] args) throws Exception {
final ServerSocket server = new ServerSocket(6502);
final Socket socket = server.accept();
final OutputStream out = socket.getOutputStream();
final InputStream in = socket.getInputStream();
Thread inThread = new Thread(new Runnable() { public void run() {
System.out.println("in, start");
try {
while (in.read() != -1) {
System.out.println(":");
}
} catch (IOException exc) {
exc.printStackTrace();
} finally {
System.out.println("in, end");
}
}});
inThread.start();
for (;;) {
Thread.sleep(1000);
out.write('X');
}
}
}

Signature
Unemployed English Java programmer
http://jroller.com/page/tackline/