Client 代码如下
package chat;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
public class GCli {
private static final int PORT = 6767;
private static final String HOST = "127.0.0.1";
private Selector selector;
private SocketChannel socketChannel;
private String name;
public static void main(String[] args) {
GCli gCli = new GCli();
new Thread(){
@Override
public void run() {
while (true) {
gCli.read();
try {
Thread.currentThread().sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLine()) {
String str = scanner.nextLine();
gCli.send(str);
}
}
public GCli() {
try {
selector = Selector.open();
socketChannel = SocketChannel.open(new InetSocketAddress(HOST, PORT));
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
name = socketChannel.getLocalAddress().toString().substring(1);
SocketAddress localAddress = socketChannel.getLocalAddress();
System.out.println(localAddress.toString());
System.out.println("客户端:"+name+" is ok");
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(String msg) {
msg = name+"说:" + msg;
try {
socketChannel.write(ByteBuffer.wrap(msg.getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void read() {
try {
int count = selector.select();
if (count > 0) {
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isReadable()) {
SocketChannel soc = (SocketChannel) key.channel();
ByteBuffer buf = ByteBuffer.allocate(1024);
int num = soc.read(buf);
System.out.println(new String(buf.array()));
}
}
iterator.remove();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server 代码如下
package chat;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;
public class GSer {
private static final int PORT = 6767;
private Selector selector;
private ServerSocketChannel serverSocketChannel;
// private
public static void main(String[] args) {
GSer gSer = new GSer();
gSer.listen();
}
public GSer() {
try {
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
// serverSocketChannel.bind(new InetSocketAddress(PORT));
serverSocketChannel.socket().bind(new InetSocketAddress(PORT));
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (Exception e) {
e.printStackTrace();
}
}
public void listen(){
while (true) {
try {
int count = selector.select();
if (count > 0) {
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> keys = selectionKeys.iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
if (key.isAcceptable()) {
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
SocketChannel serverSocket = serverSocketChannel.accept();
serverSocket.configureBlocking(false);
serverSocket.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(1234));
System.out.println("serverSocket = " + serverSocket.getRemoteAddress()+"上线了");
}
if (key.isReadable()) {
read(key);
}
keys.remove();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}
private void read(SelectionKey key) {
SocketChannel socketChannel = (SocketChannel) key.channel();
// ByteBuffer buffer= (ByteBuffer) key.attachment();
try {
ByteBuffer buffer=ByteBuffer.allocate(1213);
int count = socketChannel.read(buffer);
if (count > 0) {
String msg = new String(buffer.array());
System.out.println("read方法 = " + msg);
sendTo(msg, socketChannel);
}
} catch (IOException e) {
try {
System.out.println("socketChannel.getRemoteAddress() = " + socketChannel.getRemoteAddress()+"客户端离开了");
key.cancel();
socketChannel.close();
} catch (IOException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
}
private void sendTo(String msg, SocketChannel socketChannel) {
System.out.println("服务器开始转发了==========");
//也就是把所有注册到selector上的channel都转发一份,但是没有自身
for (SelectionKey selectionKey : selector.keys()) {
SelectableChannel soc = selectionKey.channel();
if (soc instanceof SocketChannel &&soc != socketChannel) {
try {
((SocketChannel)soc).write(ByteBuffer.wrap(msg.getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
以上代码中需要注意的问题,主要有SocketChannel 的configBlocking(false)
还有就是iterater中的问题。 要remove()既然remove 必须和next 方法配合使用。那么怎么用呢?
就是