Java Tutorial/Network/SocketChannel
Содержание
Channel selector
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
public class MainClass {
private static byte[] data = new byte[255];
public static void main(String[] args) throws IOException {
for (int i = 0; i < data.length; i++)
data[i] = (byte) i;
ServerSocketChannel server = ServerSocketChannel.open();
server.configureBlocking(false);
server.socket().bind(new InetSocketAddress(9000));
Selector selector = Selector.open();
server.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select();
Set readyKeys = selector.selectedKeys();
Iterator iterator = readyKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = (SelectionKey) iterator.next();
iterator.remove();
if (key.isAcceptable()) {
SocketChannel client = server.accept();
System.out.println("Accepted connection from " + client);
client.configureBlocking(false);
ByteBuffer source = ByteBuffer.wrap(data);
SelectionKey key2 = client.register(selector, SelectionKey.OP_WRITE);
key2.attach(source);
} else if (key.isWritable()) {
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer output = (ByteBuffer) key.attachment();
if (!output.hasRemaining()) {
output.rewind();
}
client.write(output);
}
key.channel().close();
}
}
}
}
Create SocketChannel from IP address
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.channels.SocketChannel;
public class MainClass {
public static void main(String[] args) throws Exception {
int port = 1919;
SocketAddress address = new InetSocketAddress("127.0.0.1", port);
SocketChannel client = SocketChannel.open(address);
ByteBuffer buffer = ByteBuffer.allocate(4);
IntBuffer view = buffer.asIntBuffer();
for (int expected = 0;; expected++) {
client.read(buffer);
int actual = view.get();
buffer.clear();
view.rewind();
if (actual != expected) {
System.err.println("Expected " + expected + "; was " + actual);
break;
}
System.out.println(actual);
}
}
}
Creating a Non-Blocking Socket: requires a socket channel.
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
public class Main {
public static void main(String[] argv) throws Exception {
SocketChannel sChannel = SocketChannel.open();
sChannel.configureBlocking(false);
sChannel.connect(new InetSocketAddress("hostName", 12345));
while (!sChannel.finishConnect()) {
// Do something else
}
}
}
Demonstrate asynchronous connection of a SocketChannel
import java.net.InetSocketAddress;
import java.nio.channels.SocketChannel;
public class MainClass {
public static void main(String[] argv) throws Exception {
String host = "localhost";
int port = 80;
InetSocketAddress addr = new InetSocketAddress(host, port);
SocketChannel sc = SocketChannel.open();
sc.configureBlocking(false);
System.out.println("initiating connection");
sc.connect(addr);
while (!sc.finishConnect()) {
System.out.println("doing something useless");
}
System.out.println("connection established");
sc.close();
}
}
Reading from a SocketChannel
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class Main {
public static void main(String[] argv) throws Exception {
ByteBuffer buf = ByteBuffer.allocateDirect(1024);
SocketChannel sChannel = SocketChannel.open();
sChannel.configureBlocking(false);
sChannel.connect(new InetSocketAddress("hostName", 12345));
int numBytesRead = sChannel.read(buf);
if (numBytesRead == -1) {
sChannel.close();
} else {
buf.flip();
}
}
}
Use SocketChannel to get Web page
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
public class MainClass {
public static void main(String[] args) throws IOException {
URL u = new URL("http://www.jexp.ru");
String host = u.getHost();
int port = 80;
String file = "/";
SocketAddress remote = new InetSocketAddress(host, port);
SocketChannel channel = SocketChannel.open(remote);
FileOutputStream out = new FileOutputStream("yourfile.htm");
FileChannel localFile = out.getChannel();
String request = "GET " + file + " HTTP/1.1\r\n" + "User-Agent: HTTPGrab\r\n"
+ "Accept: text/*\r\n" + "Connection: close\r\n" + "Host: " + host + "\r\n" + "\r\n";
ByteBuffer header = ByteBuffer.wrap(request.getBytes("US-ASCII"));
channel.write(header);
ByteBuffer buffer = ByteBuffer.allocate(8192);
while (channel.read(buffer) != -1) {
buffer.flip();
localFile.write(buffer);
buffer.clear();
}
localFile.close();
channel.close();
}
}
Writing to a SocketChannel
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
public class Main {
public static void main(String[] argv) throws Exception {
SocketChannel sChannel = SocketChannel.open();
sChannel.configureBlocking(false);
sChannel.connect(new InetSocketAddress("hostName", 12345));
ByteBuffer buf = ByteBuffer.allocateDirect(1024);
buf.put((byte) 0xFF);
buf.flip();
int numBytesWritten = sChannel.write(buf);
}
}