2008-02-19 18:06:52 +00:00
|
|
|
/* Copyright (c) 2008, Avian Contributors
|
|
|
|
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
|
|
for any purpose with or without fee is hereby granted, provided
|
|
|
|
that the above copyright notice and this permission notice appear
|
|
|
|
in all copies.
|
|
|
|
|
|
|
|
There is NO WARRANTY for this software. See license.txt for
|
|
|
|
details. */
|
|
|
|
|
2007-10-05 21:32:56 +00:00
|
|
|
package java.nio.channels;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
2008-11-22 22:32:53 +00:00
|
|
|
import java.net.SocketException;
|
2008-03-25 17:18:17 +00:00
|
|
|
import java.net.SocketAddress;
|
2007-10-05 21:32:56 +00:00
|
|
|
import java.net.InetSocketAddress;
|
2008-11-22 22:32:53 +00:00
|
|
|
import java.net.Socket;
|
2007-10-05 21:32:56 +00:00
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
|
|
|
|
public class SocketChannel extends SelectableChannel
|
|
|
|
implements ReadableByteChannel, WritableByteChannel
|
|
|
|
{
|
|
|
|
public static final int InvalidSocket = -1;
|
|
|
|
|
2008-11-22 22:32:53 +00:00
|
|
|
int socket = InvalidSocket;
|
|
|
|
boolean connected = false;
|
2007-10-05 21:32:56 +00:00
|
|
|
|
|
|
|
public static SocketChannel open() {
|
|
|
|
return new SocketChannel();
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:18:17 +00:00
|
|
|
public SelectableChannel configureBlocking(boolean v) {
|
2007-10-05 21:32:56 +00:00
|
|
|
if (v) throw new IllegalArgumentException();
|
2008-03-25 17:18:17 +00:00
|
|
|
return this;
|
2007-10-05 21:32:56 +00:00
|
|
|
}
|
|
|
|
|
2008-11-22 22:32:53 +00:00
|
|
|
public Socket socket() {
|
|
|
|
return new Handle();
|
|
|
|
}
|
|
|
|
|
2008-03-25 17:18:17 +00:00
|
|
|
public boolean connect(SocketAddress address) throws Exception {
|
|
|
|
InetSocketAddress a;
|
|
|
|
try {
|
|
|
|
a = (InetSocketAddress) address;
|
|
|
|
} catch (ClassCastException e) {
|
|
|
|
throw new UnsupportedAddressTypeException();
|
|
|
|
}
|
|
|
|
socket = doConnect(a.getHostName(), a.getPort());
|
|
|
|
return connected;
|
2007-10-05 21:32:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void close() throws IOException {
|
2008-03-25 22:17:29 +00:00
|
|
|
if (isOpen()) {
|
2008-03-25 17:18:17 +00:00
|
|
|
super.close();
|
|
|
|
closeSocket();
|
|
|
|
}
|
2007-10-05 21:32:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private int doConnect(String host, int port) throws Exception {
|
|
|
|
boolean b[] = new boolean[1];
|
|
|
|
int s = natDoConnect(host, port, b);
|
|
|
|
connected = b[0];
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int read(ByteBuffer b) throws IOException {
|
2008-03-25 17:18:17 +00:00
|
|
|
if (! isOpen()) return -1;
|
2007-10-05 21:32:56 +00:00
|
|
|
if (b.remaining() == 0) return 0;
|
|
|
|
int r = natRead(socket, b.array(), b.arrayOffset() + b.position(), b.remaining());
|
2007-10-07 15:53:07 +00:00
|
|
|
if (r > 0) {
|
|
|
|
b.position(b.position() + r);
|
|
|
|
}
|
2007-10-05 21:32:56 +00:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
public int write(ByteBuffer b) throws IOException {
|
|
|
|
if (! connected) {
|
|
|
|
natThrowWriteError(socket);
|
|
|
|
}
|
2007-10-11 21:41:23 +00:00
|
|
|
if (b.remaining() == 0) return 0;
|
2007-10-05 21:32:56 +00:00
|
|
|
int w = natWrite(socket, b.array(), b.arrayOffset() + b.position(), b.remaining());
|
2007-10-07 17:35:48 +00:00
|
|
|
if (w > 0) {
|
|
|
|
b.position(b.position() + w);
|
|
|
|
}
|
2007-10-05 21:32:56 +00:00
|
|
|
return w;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void closeSocket() {
|
|
|
|
natCloseSocket(socket);
|
|
|
|
}
|
|
|
|
|
|
|
|
int socketFD() {
|
|
|
|
return socket;
|
|
|
|
}
|
|
|
|
|
2008-11-22 22:32:53 +00:00
|
|
|
public class Handle extends Socket {
|
|
|
|
public void setTcpNoDelay(boolean on) throws SocketException {
|
|
|
|
natSetTcpNoDelay(socket, on);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static native void natSetTcpNoDelay(int socket, boolean on)
|
|
|
|
throws SocketException;
|
|
|
|
|
2007-10-05 21:32:56 +00:00
|
|
|
private static native int natDoConnect(String host, int port, boolean[] connected)
|
|
|
|
throws Exception;
|
|
|
|
private static native int natRead(int socket, byte[] buffer, int offset, int length)
|
|
|
|
throws IOException;
|
|
|
|
private static native int natWrite(int socket, byte[] buffer, int offset, int length)
|
|
|
|
throws IOException;
|
|
|
|
private static native void natThrowWriteError(int socket) throws IOException;
|
|
|
|
private static native void natCloseSocket(int socket);
|
|
|
|
}
|