展开全部
首先你要懂得NIO才行,看看下面的例子,你就会写了。
import java.io.IOException;
import java.nio.channels.SelectionKey;
/**
* Created by IntelliJ IDEA.
* User: hongruixing
* Date: 2008-3-31
* Time: 14:49:31
* To change this template use File | Settings | File Templates.
*/
public interface Reactor {
/**
* React to an NIO event.
*
* @62616964757a686964616fe58685e5aeb931333236376461param key SelectionKey which has a ready operation.
*/
void react(SelectionKey key) throws IOException;
}
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
/**
* Created by IntelliJ IDEA.
* User: hongruixing
* Date: 2008-3-31
* Time: 14:49:59
* To change this template use File | Settings | File Templates.
*/
public class Acceptor implements Reactor {
public void react(SelectionKey key) throws IOException {
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel sc = ssc.accept();
if (sc != null) {
sc.configureBlocking(false);
sc.register(key.selector(), SelectionKey.OP_READ, new Reader(ByteBuffer.allocate(1024)));
}
}
}
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
/**
* Created by IntelliJ IDEA.
* User: hongruixing
* Date: 2008-3-31
* Time: 14:50:39
* To change this template use File | Settings | File Templates.
*/
public class Reader implements Reactor {
ByteBuffer buffer;
/**
* Constructs a Reader.
*
* @param buffer ByteBuffer for I/O.
*/
public Reader(ByteBuffer buffer) {
this.buffer = buffer;
}
public void react(SelectionKey key) throws IOException {
SocketChannel sc = (SocketChannel) key.channel();
int count;
while ((count = sc.read(buffer)) > 0 || buffer.position() > 0) {
try {
buffer.flip();
count = sc.write(buffer);
if (count == 0) {
// Stop reading this channel and wait for an OP_WRITE
sc.register(key.selector(), SelectionKey.OP_WRITE, new Writer(buffer));
return;
}
}
finally {
buffer.compact();
}
}
if (count < 0) {
sc.close();
}
}
}
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
/**
* Created by IntelliJ IDEA.
* User: hongruixing
* Date: 2008-3-31
* Time: 14:51:18
* To change this template use File | Settings | File Templates.
*/
public class Writer implements Reactor {
ByteBuffer buffer;
/**
* Constructs a Writer.
*
* @param buffer ByteBuffer for I/O.
*/
public Writer(ByteBuffer buffer) {
this.buffer = buffer;
}
public void react(SelectionKey key) throws IOException {
try {
SocketChannel sc = (SocketChannel) key.channel();
buffer.flip();
int count = sc.write(buffer);
if (!buffer.hasRemaining())
// Nothing left to write: OK to start reading again
sc.register(key.selector(), SelectionKey.OP_READ, new Reader(buffer));
}
finally {
buffer.compact();
}
}
}
import java.beans.PropertyChangeSupport;
import java.io.Closeable;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.ClosedSelectorException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
public class EchoServer implements Closeable, Runnable {
private static final Map operations = new HashMap();
private Logger logger = Logger.getLogger(this.getClass().getName());
private ServerSocketChannel ssc;
private Selector selector;
/**
* Creates a new instance of EchoServer.
*
* @param port Port number to listen at.
*/
public EchoServer(int port) throws IOException {
this.ssc = ServerSocketChannel.open();
this.selector = Selector.open();
ssc.socket().bind(new InetSocketAddress(port));
ssc.configureBlocking(false);
ssc.register(selector, SelectionKey.OP_ACCEPT, new Acceptor());
}
static {
operations.put(SelectionKey.OP_ACCEPT, "OP_ACCEPT");
operations.put(SelectionKey.OP_CONNECT, "OP_CONNECT");
operations.put(SelectionKey.OP_READ, "OP_READ");
operations.put(SelectionKey.OP_WRITE, "OP_WRITE");
}
static String getOperations(int ops) {
String result = "";
for (int i = 1; i < 32; i <<= 1) {
if ((ops & i) == 0)
continue;
if (result.length() > 0)
result += ",";
result += operations.get(i);
}
return result;
}
public void close() throws IOException {
ssc.close();
selector.close();
}
public void run() {
while (selector.isOpen()) {
try {
int nsel = selector.select(timeout);
if (nsel == 0) {
// TODO: timeout
for (SelectionKey key : selector.keys()) {
logger.log(Level.INFO, "channel " + key.channel() + " waiting for " + getOperations(key.interestOps()));
}
continue;
}
Iterator it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
it.remove();
if (!key.isValid() || !key.channel().isOpen())
// e.g.OP_ACCEPT is triggered once when the channel is closed.
continue;
Reactor reactor = (Reactor) key.attachment();
try {
reactor.react(key);
}
catch (IOException exc) {
logger.log(Level.SEVERE, "calling Reactor.react()", exc);
}
}
}
catch (ClosedSelectorException exc) {
logger.log(Level.FINE, "select loop", exc);
}
catch (IOException exc) {
logger.log(Level.SEVERE, "select loop", exc);
}
}
}
/**
* Utility field used by bound properties.
*/
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
/**
* Adds a PropertyChangeListener to the listener list.
*
* @param l The listener to add.
*/
public void addPropertyChangeListener(java.beans.PropertyChangeListener l) {
propertyChangeSupport.addPropertyChangeListener(l);
}
/**
* Removes a PropertyChangeListener from the listener list.
*
* @param l The listener to remove.
*/
public void removePropertyChangeListener(java.beans.PropertyChangeListener l) {
propertyChangeSupport.removePropertyChangeListener(l);
}
/**
* Holds value of property timeout.
*/
private int timeout;
/**
* Getter for property timeout.
*
* @return Value of property timeout.
*/
public int getTimeout() {
return this.timeout;
}
/**
* Setter for property timeout.
*
* @param timeout New value of property timeout.
*/
public void setTimeout(int timeout) {
int oldTimeout = this.timeout;
this.timeout = timeout;
propertyChangeSupport.firePropertyChange("timeout", new Integer(oldTimeout), new Integer(timeout));
}
/**
* Main method, for testing.
*
* @param args Command line arguments.
*/
public static void main(String[] args) throws IOException {
int port = 8082;
EchoServer server = new EchoServer(port);
server.setTimeout(10 * 1000);
new Thread(server).start();
while (true) {
}
}
}
本回答由网友推荐
已赞过
已踩过<
你对这个回答的评价是?
评论
收起