mirror of
https://github.com/corda/corda.git
synced 2025-06-13 12:48:18 +00:00
Implement socket API
This commit is contained in:
committed by
Joshua Warner
parent
2800ffe826
commit
45ee25f68c
@ -10,10 +10,191 @@
|
||||
|
||||
package java.net;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public abstract class Socket {
|
||||
public static native void init() throws IOException;
|
||||
public class Socket implements Closeable, AutoCloseable {
|
||||
|
||||
public abstract void setTcpNoDelay(boolean on) throws SocketException;
|
||||
private static final int SD_RECEIVE = 0x00;
|
||||
private static final int SD_SEND = 0x01;
|
||||
private static final int SD_BOTH = 0x02;
|
||||
|
||||
private static final int BUFFER_SIZE = 65535;
|
||||
|
||||
/**
|
||||
* This method is called from all routines that depend on winsock in windows,
|
||||
* so it has public visibility
|
||||
* @throws IOException
|
||||
*/
|
||||
public static native void init() throws IOException;
|
||||
|
||||
/**
|
||||
* Creates the native socket object
|
||||
* @return Handle to the native object
|
||||
* @throws IOException
|
||||
*/
|
||||
private static native /* SOCKET */long create() throws IOException;
|
||||
|
||||
/**
|
||||
* Connects the native socket object to an address:port
|
||||
* @param sock Native socket handler
|
||||
* @param addr Address to connect to
|
||||
* @param port Port to connect to
|
||||
* @throws IOException
|
||||
*/
|
||||
private static native void connect(/* SOCKET */long sock, long addr, short port) throws IOException;
|
||||
private static native void bind(/* SOCKET */long sock, long addr, short port) throws IOException;
|
||||
|
||||
private static native void send(/* SOCKET */long sock, byte[] buffer, int start_pos, int count) throws IOException;
|
||||
private static native int recv(/* SOCKET */long sock, byte[] buffer, int start_pos, int count) throws IOException;
|
||||
|
||||
private static native void abort(/* SOCKET */long sock);
|
||||
private static native void close(/* SOCKET */long sock);
|
||||
private static native void closeOutput(/* SOCKET */long sock);
|
||||
private static native void closeInput(/* SOCKET */long sock);
|
||||
|
||||
private class SocketInputStream extends InputStream {
|
||||
|
||||
private boolean closed = false;
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (!closed) {
|
||||
closeInput(sock);
|
||||
closed = true;
|
||||
}
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
close();
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
byte[] buffer = new byte[1];
|
||||
int size = recv(sock, buffer, 0, 1);
|
||||
if (size == 0) {
|
||||
return -1;
|
||||
}
|
||||
return buffer[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] buffer) throws IOException {
|
||||
int fullSize = buffer.length;
|
||||
int index = 0;
|
||||
int size;
|
||||
do {
|
||||
size = recv(sock, buffer, index, Math.min(fullSize, Socket.BUFFER_SIZE));
|
||||
fullSize -= size;
|
||||
index += size;
|
||||
} while (fullSize != 0 && size != 0);
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private class SocketOutputStream extends OutputStream {
|
||||
|
||||
private boolean closed = false;
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (!closed) {
|
||||
closeOutput(sock);
|
||||
closed = true;
|
||||
}
|
||||
super.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
close();
|
||||
super.finalize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int c) throws IOException {
|
||||
byte[] res = new byte[1];
|
||||
res[0] = (byte)c;
|
||||
send(sock, res, 0, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(byte[] buffer) throws IOException {
|
||||
int fullSize = buffer.length;
|
||||
int index = 0;
|
||||
int size;
|
||||
do {
|
||||
size = Math.min(fullSize, Socket.BUFFER_SIZE);
|
||||
send(sock, buffer, index, size);
|
||||
fullSize -= size;
|
||||
index += size;
|
||||
} while (fullSize != 0 && size != 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private long sock;
|
||||
private SocketInputStream inputStream;
|
||||
private SocketOutputStream outputStream;
|
||||
|
||||
public Socket() throws IOException {
|
||||
Socket.init();
|
||||
sock = create();
|
||||
inputStream = new SocketInputStream();
|
||||
outputStream = new SocketOutputStream();
|
||||
}
|
||||
|
||||
public SocketInputStream getInputStream() {
|
||||
return inputStream;
|
||||
}
|
||||
|
||||
public SocketOutputStream getOutputStream() {
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
public Socket(InetAddress address, int port) throws IOException {
|
||||
this();
|
||||
connect(sock, address.getRawAddress(), (short)port);
|
||||
}
|
||||
|
||||
public Socket(String host, int port) throws UnknownHostException, IOException {
|
||||
this(InetAddress.getByName(host), port);
|
||||
}
|
||||
|
||||
public void bind(SocketAddress bindpoint) throws IOException {
|
||||
if (bindpoint instanceof InetSocketAddress) {
|
||||
InetSocketAddress inetBindpoint = (InetSocketAddress)bindpoint;
|
||||
bind(sock, inetBindpoint.getAddress().getRawAddress(), (short) inetBindpoint.getPort());
|
||||
}
|
||||
}
|
||||
|
||||
public void setTcpNoDelay(boolean on) throws SocketException {}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
close(sock);
|
||||
}
|
||||
|
||||
public void shutdownInput() throws IOException {
|
||||
inputStream.close();
|
||||
}
|
||||
|
||||
public void shutdownOutput() throws IOException {
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void finalize() throws Throwable {
|
||||
close();
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user