Java Tutorial/Network/SocketChannel

Материал из Java эксперт
Перейти к: навигация, поиск

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);
  }
}