add minimal java.net.Socket implementation to support Socket.setTcpNoDelay

This commit is contained in:
Joel Dice 2008-11-22 15:32:53 -07:00
parent 6162dfafbb
commit fccf906349
5 changed files with 111 additions and 5 deletions

View File

@ -26,6 +26,7 @@
# include <errno.h> # include <errno.h>
# include <netdb.h> # include <netdb.h>
# include <sys/select.h> # include <sys/select.h>
# include <netinet/tcp.h>
#endif #endif
#define java_nio_channels_SelectionKey_OP_READ 1L #define java_nio_channels_SelectionKey_OP_READ 1L
@ -88,6 +89,26 @@ throwIOException(JNIEnv* e)
throwIOException(e, errorString(e)); throwIOException(e, errorString(e));
} }
void
throwSocketException(JNIEnv* e, const char* s)
{
throwNew(e, "java/net/SocketException", s);
}
void
throwSocketException(JNIEnv* e, jbyteArray a)
{
jbyte* s = static_cast<jbyte*>(e->GetPrimitiveArrayCritical(a, 0));
throwSocketException(e, reinterpret_cast<const char*>(s));
e->ReleasePrimitiveArrayCritical(a, s, 0);
}
void
throwSocketException(JNIEnv* e)
{
throwSocketException(e, errorString(e));
}
void void
init(JNIEnv* e, sockaddr_in* address, jstring hostString, jint port) init(JNIEnv* e, sockaddr_in* address, jstring hostString, jint port)
{ {
@ -152,6 +173,19 @@ makeNonblocking(JNIEnv* e, int d)
return true; return true;
} }
bool
setTcpNoDelay(JNIEnv* e, int d, bool on)
{
int flag = on;
int r = setsockopt
(d, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&flag), sizeof(int));
if (r < 0) {
throwSocketException(e);
return false;
}
return true;
}
void void
doListen(JNIEnv* e, int s, sockaddr_in* address) doListen(JNIEnv* e, int s, sockaddr_in* address)
{ {
@ -277,6 +311,15 @@ Java_java_nio_channels_ServerSocketChannel_natDoListen(JNIEnv *e,
return s; return s;
} }
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_natSetTcpNoDelay(JNIEnv *e,
jclass,
jint socket,
jboolean on)
{
setTcpNoDelay(e, socket, on);
}
extern "C" JNIEXPORT jint JNICALL extern "C" JNIEXPORT jint JNICALL
Java_java_nio_channels_SocketChannel_natDoConnect(JNIEnv *e, Java_java_nio_channels_SocketChannel_natDoConnect(JNIEnv *e,
jclass, jclass,

View File

@ -0,0 +1,15 @@
/* 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. */
package java.net;
public abstract class Socket {
public abstract void setTcpNoDelay(boolean on) throws SocketException;
}

View File

@ -0,0 +1,23 @@
/* 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. */
package java.net;
import java.io.IOException;
public class SocketException extends IOException {
public SocketException(String message) {
super(message);
}
public SocketException() {
this(null);
}
}

View File

@ -16,11 +16,21 @@ import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
public class ServerSocketChannel extends SocketChannel { public class ServerSocketChannel extends SelectableChannel {
private final SocketChannel channel = new SocketChannel();
public static ServerSocketChannel open() { public static ServerSocketChannel open() {
return new ServerSocketChannel(); return new ServerSocketChannel();
} }
public SelectableChannel configureBlocking(boolean v) {
return channel.configureBlocking(v);
}
public void close() throws IOException {
channel.close();
}
public SocketChannel accept() throws Exception { public SocketChannel accept() throws Exception {
SocketChannel c = new SocketChannel(); SocketChannel c = new SocketChannel();
c.socket = doAccept(); c.socket = doAccept();
@ -33,7 +43,7 @@ public class ServerSocketChannel extends SocketChannel {
} }
private int doAccept() throws IOException { private int doAccept() throws IOException {
return natDoAccept(socket); return natDoAccept(channel.socket);
} }
private int doListen(String host, int port) throws IOException { private int doListen(String host, int port) throws IOException {
@ -50,7 +60,7 @@ public class ServerSocketChannel extends SocketChannel {
} catch (ClassCastException e) { } catch (ClassCastException e) {
throw new IllegalArgumentException(); throw new IllegalArgumentException();
} }
socket = doListen(a.getHostName(), a.getPort()); channel.socket = doListen(a.getHostName(), a.getPort());
} }
} }

View File

@ -11,8 +11,10 @@
package java.nio.channels; package java.nio.channels;
import java.io.IOException; import java.io.IOException;
import java.net.SocketException;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
public class SocketChannel extends SelectableChannel public class SocketChannel extends SelectableChannel
@ -20,8 +22,8 @@ public class SocketChannel extends SelectableChannel
{ {
public static final int InvalidSocket = -1; public static final int InvalidSocket = -1;
protected int socket = InvalidSocket; int socket = InvalidSocket;
protected boolean connected = false; boolean connected = false;
public static SocketChannel open() { public static SocketChannel open() {
return new SocketChannel(); return new SocketChannel();
@ -32,6 +34,10 @@ public class SocketChannel extends SelectableChannel
return this; return this;
} }
public Socket socket() {
return new Handle();
}
public boolean connect(SocketAddress address) throws Exception { public boolean connect(SocketAddress address) throws Exception {
InetSocketAddress a; InetSocketAddress a;
try { try {
@ -87,6 +93,15 @@ public class SocketChannel extends SelectableChannel
return socket; return socket;
} }
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;
private static native int natDoConnect(String host, int port, boolean[] connected) private static native int natDoConnect(String host, int port, boolean[] connected)
throws Exception; throws Exception;
private static native int natRead(int socket, byte[] buffer, int offset, int length) private static native int natRead(int socket, byte[] buffer, int offset, int length)