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 <netdb.h>
# include <sys/select.h>
# include <netinet/tcp.h>
#endif
#define java_nio_channels_SelectionKey_OP_READ 1L
@ -88,6 +89,26 @@ throwIOException(JNIEnv* 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
init(JNIEnv* e, sockaddr_in* address, jstring hostString, jint port)
{
@ -152,6 +173,19 @@ makeNonblocking(JNIEnv* e, int d)
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
doListen(JNIEnv* e, int s, sockaddr_in* address)
{
@ -277,6 +311,15 @@ Java_java_nio_channels_ServerSocketChannel_natDoListen(JNIEnv *e,
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
Java_java_nio_channels_SocketChannel_natDoConnect(JNIEnv *e,
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.ServerSocket;
public class ServerSocketChannel extends SocketChannel {
public class ServerSocketChannel extends SelectableChannel {
private final SocketChannel channel = new SocketChannel();
public static ServerSocketChannel open() {
return new ServerSocketChannel();
}
public SelectableChannel configureBlocking(boolean v) {
return channel.configureBlocking(v);
}
public void close() throws IOException {
channel.close();
}
public SocketChannel accept() throws Exception {
SocketChannel c = new SocketChannel();
c.socket = doAccept();
@ -33,7 +43,7 @@ public class ServerSocketChannel extends SocketChannel {
}
private int doAccept() throws IOException {
return natDoAccept(socket);
return natDoAccept(channel.socket);
}
private int doListen(String host, int port) throws IOException {
@ -50,7 +60,7 @@ public class ServerSocketChannel extends SocketChannel {
} catch (ClassCastException e) {
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;
import java.io.IOException;
import java.net.SocketException;
import java.net.SocketAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
public class SocketChannel extends SelectableChannel
@ -20,8 +22,8 @@ public class SocketChannel extends SelectableChannel
{
public static final int InvalidSocket = -1;
protected int socket = InvalidSocket;
protected boolean connected = false;
int socket = InvalidSocket;
boolean connected = false;
public static SocketChannel open() {
return new SocketChannel();
@ -32,6 +34,10 @@ public class SocketChannel extends SelectableChannel
return this;
}
public Socket socket() {
return new Handle();
}
public boolean connect(SocketAddress address) throws Exception {
InetSocketAddress a;
try {
@ -87,6 +93,15 @@ public class SocketChannel extends SelectableChannel
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)
throws Exception;
private static native int natRead(int socket, byte[] buffer, int offset, int length)