mirror of
https://github.com/corda/corda.git
synced 2025-01-19 11:16:54 +00:00
implement DatagramChannel.receive and fix Datagrams to be Java 6 compatible
This commit is contained in:
parent
d8483d720d
commit
9974d91648
@ -337,6 +337,26 @@ doRead(int fd, void* buffer, size_t count)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
doRecv(int fd, void* buffer, size_t count, int32_t* host, int32_t* port)
|
||||||
|
{
|
||||||
|
sockaddr address;
|
||||||
|
socklen_t length = sizeof(address);
|
||||||
|
int r = recvfrom
|
||||||
|
(fd, static_cast<char*>(buffer), count, 0, &address, &length);
|
||||||
|
|
||||||
|
if (r > 0) {
|
||||||
|
sockaddr_in a; memcpy(&a, &address, length);
|
||||||
|
*host = ntohl(a.sin_addr.s_addr);
|
||||||
|
*port = ntohs(a.sin_port);
|
||||||
|
} else {
|
||||||
|
*host = 0;
|
||||||
|
*port = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
doWrite(int fd, const void* buffer, size_t count)
|
doWrite(int fd, const void* buffer, size_t count)
|
||||||
{
|
{
|
||||||
@ -529,16 +549,54 @@ Java_java_nio_channels_SocketChannel_natRead(JNIEnv *e,
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
Java_java_nio_channels_DatagramChannel_read(JNIEnv* e,
|
Java_java_nio_channels_DatagramChannel_receive(JNIEnv* e,
|
||||||
jclass c,
|
jclass,
|
||||||
jint socket,
|
jint socket,
|
||||||
jbyteArray buffer,
|
jbyteArray buffer,
|
||||||
jint offset,
|
jint offset,
|
||||||
jint length,
|
jint length,
|
||||||
jboolean blocking)
|
jboolean blocking,
|
||||||
|
jintArray address)
|
||||||
{
|
{
|
||||||
return Java_java_nio_channels_SocketChannel_natRead
|
int r;
|
||||||
(e, c, socket, buffer, offset, length, blocking);
|
int32_t host;
|
||||||
|
int32_t port;
|
||||||
|
if (blocking) {
|
||||||
|
uint8_t* buf = static_cast<uint8_t*>(allocate(e, length));
|
||||||
|
if (buf) {
|
||||||
|
r = ::doRecv(socket, buf, length, &host, &port);
|
||||||
|
if (r > 0) {
|
||||||
|
e->SetByteArrayRegion
|
||||||
|
(buffer, offset, r, reinterpret_cast<jbyte*>(buf));
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
jboolean isCopy;
|
||||||
|
uint8_t* buf = static_cast<uint8_t*>
|
||||||
|
(e->GetPrimitiveArrayCritical(buffer, &isCopy));
|
||||||
|
|
||||||
|
r = ::doRecv(socket, buf + offset, length, &host, &port);
|
||||||
|
|
||||||
|
e->ReleasePrimitiveArrayCritical(buffer, buf, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r < 0) {
|
||||||
|
if (eagain()) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
throwIOException(e);
|
||||||
|
}
|
||||||
|
} else if (r == 0) {
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
e->SetIntArrayRegion(address, 0, 1, &host);
|
||||||
|
e->SetIntArrayRegion(address, 1, 1, &port);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
19
classpath/java/net/DatagramSocket.java
Normal file
19
classpath/java/net/DatagramSocket.java
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
/* Copyright (c) 2012, 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 abstract class DatagramSocket {
|
||||||
|
public abstract SocketAddress getRemoteSocketAddress();
|
||||||
|
|
||||||
|
public abstract void bind(SocketAddress address) throws SocketException;
|
||||||
|
}
|
@ -16,6 +16,8 @@ import java.net.SocketAddress;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.ProtocolFamily;
|
import java.net.ProtocolFamily;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
import java.net.StandardProtocolFamily;
|
import java.net.StandardProtocolFamily;
|
||||||
|
|
||||||
public class DatagramChannel extends SelectableChannel
|
public class DatagramChannel extends SelectableChannel
|
||||||
@ -26,7 +28,7 @@ public class DatagramChannel extends SelectableChannel
|
|||||||
private int socket = InvalidSocket;
|
private int socket = InvalidSocket;
|
||||||
private boolean blocking = true;
|
private boolean blocking = true;
|
||||||
|
|
||||||
public DatagramChannel configureBlocking(boolean v) throws IOException {
|
public SelectableChannel configureBlocking(boolean v) throws IOException {
|
||||||
blocking = v;
|
blocking = v;
|
||||||
if (socket != InvalidSocket) {
|
if (socket != InvalidSocket) {
|
||||||
configureBlocking(socket, v);
|
configureBlocking(socket, v);
|
||||||
@ -54,6 +56,16 @@ public class DatagramChannel extends SelectableChannel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static DatagramChannel open()
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
return open(StandardProtocolFamily.INET);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DatagramSocket socket() {
|
||||||
|
return new Handle();
|
||||||
|
}
|
||||||
|
|
||||||
public DatagramChannel bind(SocketAddress address) throws IOException {
|
public DatagramChannel bind(SocketAddress address) throws IOException {
|
||||||
InetSocketAddress inetAddress;
|
InetSocketAddress inetAddress;
|
||||||
try {
|
try {
|
||||||
@ -97,19 +109,59 @@ public class DatagramChannel extends SelectableChannel
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int read(ByteBuffer b) throws IOException {
|
public int read(ByteBuffer b) throws IOException {
|
||||||
if (b.remaining() == 0) return 0;
|
int p = b.position();
|
||||||
|
receive(b);
|
||||||
|
return b.position() - p;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SocketAddress receive(ByteBuffer b) throws IOException {
|
||||||
|
if (b.remaining() == 0) return null;
|
||||||
|
|
||||||
byte[] array = b.array();
|
byte[] array = b.array();
|
||||||
if (array == null) throw new NullPointerException();
|
if (array == null) throw new NullPointerException();
|
||||||
|
|
||||||
int c = read
|
int[] address = new int[2];
|
||||||
(socket, array, b.arrayOffset() + b.position(), b.remaining(), blocking);
|
|
||||||
|
int c = receive
|
||||||
|
(socket, array, b.arrayOffset() + b.position(), b.remaining(), blocking,
|
||||||
|
address);
|
||||||
|
|
||||||
if (c > 0) {
|
if (c > 0) {
|
||||||
b.position(b.position() + c);
|
b.position(b.position() + c);
|
||||||
|
|
||||||
|
return new InetSocketAddress(ipv4ToString(address[0]), address[1]);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String ipv4ToString(int address) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.append( address >> 24 ).append('.')
|
||||||
|
.append((address >> 16) & 0xFF).append('.')
|
||||||
|
.append((address >> 8) & 0xFF).append('.')
|
||||||
|
.append( address & 0xFF);
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Handle extends DatagramSocket {
|
||||||
|
public SocketAddress getRemoteSocketAddress() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
public void bind(SocketAddress address) throws SocketException {
|
||||||
|
try {
|
||||||
|
DatagramChannel.this.bind(address);
|
||||||
|
} catch (SocketException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (IOException e) {
|
||||||
|
SocketException se = new SocketException();
|
||||||
|
se.initCause(e);
|
||||||
|
throw se;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static native void configureBlocking(int socket, boolean blocking)
|
private static native void configureBlocking(int socket, boolean blocking)
|
||||||
@ -121,7 +173,8 @@ public class DatagramChannel extends SelectableChannel
|
|||||||
private static native int write(int socket, byte[] array, int offset,
|
private static native int write(int socket, byte[] array, int offset,
|
||||||
int length, boolean blocking)
|
int length, boolean blocking)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
private static native int read(int socket, byte[] array, int offset,
|
private static native int receive(int socket, byte[] array, int offset,
|
||||||
int length, boolean blocking)
|
int length, boolean blocking,
|
||||||
|
int[] address)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
}
|
}
|
||||||
|
@ -27,15 +27,15 @@ public class Datagrams {
|
|||||||
final SocketAddress Address = new InetSocketAddress(Hostname, Port);
|
final SocketAddress Address = new InetSocketAddress(Hostname, Port);
|
||||||
final byte[] Message = "hello, world!".getBytes();
|
final byte[] Message = "hello, world!".getBytes();
|
||||||
|
|
||||||
DatagramChannel out = DatagramChannel.open(StandardProtocolFamily.INET);
|
DatagramChannel out = DatagramChannel.open();
|
||||||
try {
|
try {
|
||||||
out.configureBlocking(false);
|
out.configureBlocking(false);
|
||||||
out.connect(Address);
|
out.connect(Address);
|
||||||
|
|
||||||
DatagramChannel in = DatagramChannel.open(StandardProtocolFamily.INET);
|
DatagramChannel in = DatagramChannel.open();
|
||||||
try {
|
try {
|
||||||
in.configureBlocking(false);
|
in.configureBlocking(false);
|
||||||
in.bind(Address);
|
in.socket().bind(Address);
|
||||||
|
|
||||||
Selector selector = Selector.open();
|
Selector selector = Selector.open();
|
||||||
try {
|
try {
|
||||||
@ -60,7 +60,7 @@ public class Datagrams {
|
|||||||
|
|
||||||
case 1: {
|
case 1: {
|
||||||
if (inKey.isReadable()) {
|
if (inKey.isReadable()) {
|
||||||
in.read(inBuffer);
|
in.receive(inBuffer);
|
||||||
if (! inBuffer.hasRemaining()) {
|
if (! inBuffer.hasRemaining()) {
|
||||||
expect(equal(inBuffer.array(),
|
expect(equal(inBuffer.array(),
|
||||||
inBuffer.arrayOffset(),
|
inBuffer.arrayOffset(),
|
||||||
|
Loading…
Reference in New Issue
Block a user