第一、无阻塞服务器与客户端
主要功能:客户端发一个名字过去(目前只能是英文,比如jack);服务器就会给客户端返回hello jack!
服务器:
public class Server {
public static final int PORT = 8888;
private Selector selector;
private ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
private ByteBuffer receiverBuffer = ByteBuffer.allocate(1024);
private Set<SelectionKey> keys;
public static void main(String[] args) {
try {
Server s = new Server();
s.initServer();
s.listen();
} catch (IOException e) {
e.printStackTrace();
}
}
// 初始化服务器
public void initServer() throws IOException {
selector = Selector.open();
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
ServerSocket ss = ssc.socket();
ss.bind(new InetSocketAddress(PORT));
ssc.register(selector, SelectionKey.OP_ACCEPT);
}
// 开始进行对客户端的监听
public void listen() throws IOException {
while (true) {
selector.select();
keys = selector.selectedKeys();
for (SelectionKey sk : keys) {
if (sk.isAcceptable()) {
ServerSocketChannel ssc = (ServerSocketChannel) sk.channel();
SocketChannel sc = ssc.accept();
sc.configureBlocking(false);
sc.register(selector, SelectionKey.OP_READ);
}
if (sk.isReadable()) {
SocketChannel sc = (SocketChannel) sk.channel();
receiverBuffer.clear();
StringBuilder sb = new StringBuilder();
while (sc.read(receiverBuffer) > 0) {
receiverBuffer.flip();
// 由于buffer的clear方法不是清空buffer中以前数据,只是重置position与limit,所以在取数据的时候需要下面的操作
String temp = new String(receiverBuffer.array(), receiverBuffer.position(), receiverBuffer.limit());
sb.append(temp);
receiverBuffer.clear();
}
System.out.println(sb.toString());
// 这里需要trim()下
sc.register(selector, SelectionKey.OP_WRITE, sb.toString().trim());
}
if (sk.isWritable()) {
SocketChannel sc = (SocketChannel) sk.channel();
sendBuffer.clear();
sendBuffer.put("hello ".getBytes());
String temp = (String) sk.attachment();
sendBuffer.put(temp.getBytes());
sendBuffer.put("!".getBytes());
sendBuffer.flip();
System.out.println(new String(sendBuffer.array()));
// 处理关闭
if (temp.equals("exit")) {
sc.write(ByteBuffer.wrap("exit".getBytes()));
sk.cancel();
sc.close();
} else {
sc.write(sendBuffer);
sc.register(selector, SelectionKey.OP_READ);
}
}
keys.remove(sk);
}
}
}
}
客户端:
public class Client {
private InetSocketAddress inetSocketAddress = new InetSocketAddress("localhost", 8888);
private Selector selector;
private SocketChannel sc;
public static int PORT = 8888;
public static String IP = "localhost";
public static int SIZE = 1024;
private ByteBuffer sendBuffer = ByteBuffer.allocate(1024);
private ByteBuffer receiverBuffer = ByteBuffer.allocate(1024);
public static void main(String[] args) {
try {
Client cn = new Client();
//cn.initClient();
cn.listen();
} catch (IOException e) {
e.printStackTrace();
}
}
public void initClient() throws IOException {
selector = Selector.open();
sc = SocketChannel.open();
//配置无阻塞状态需要在连接前面
sc.configureBlocking(false);
sc.connect(inetSocketAddress);
sc.register(selector, SelectionKey.OP_CONNECT);
}
public void listen() throws IOException {
initClient();
while(true) {
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
for(SelectionKey sk:keys) {
if(sk.isConnectable()) {
SocketChannel sc = (SocketChannel)sk.channel();
if(sc.isConnectionPending()) {
sc.finishConnect();
}
sc.register(selector, SelectionKey.OP_WRITE);
}
else if(sk.isWritable()) {
SocketChannel sc = (SocketChannel)sk.channel();
Scanner scanner = new Scanner(System.in);
if(scanner.hasNext()) {
sendBuffer.clear();
String temp = scanner.next().trim();
System.out.println(temp);
sendBuffer.put(temp.getBytes());
sendBuffer.flip();
sc.write(sendBuffer);
sc.register(selector, SelectionKey.OP_READ);
}
}else if(sk.isReadable()) {
SocketChannel sc = (SocketChannel)sk.channel();
receiverBuffer.clear();
StringBuilder sb = new StringBuilder();
while(sc.read(receiverBuffer)>0){
receiverBuffer.flip();
if(receiverBuffer.hasArray()) {
sb.append(new String(receiverBuffer.array(),receiverBuffer.position(),receiverBuffer.limit()));
}
};
System.out.println(sb.toString());
if(sb.toString().trim().equals("exit")) {
if(sc != null) {
sc.close();
sc = null;
}
if(selector != null) {
selector.close();
selector = null;
}
return;
}
sc.register(selector, SelectionKey.OP_WRITE);
}
keys.remove(sk);
}
}
}
}
第二、buffer
public class BufferTest {
public static void main(String[] args) {
//用wrap来构造一个buffer
CharBuffer cb1 = CharBuffer.wrap("hello world!");
System.out.println(cb1.position());
System.out.println(cb1.limit());
System.out.println(cb1.toString());
//用allocate来构造一个buffer
CharBuffer cb =CharBuffer.allocate(12);
//往buffer里放入元素
cb.put("hello world!");
//这是把limit掷成position,把position掷成0
cb.flip();
System.out.println(cb.position());
System.out.println(cb.limit());
while(cb.hasRemaining()) {
//从buffer里取得元素
System.out.print(cb.get());
}
System.out.println();
//把position重新掷成0,limit不变
cb.rewind();
System.out.println(cb.position());
System.out.println(cb.limit());
//取得前2个元素
cb.get();
cb.get();
//做压缩操作,把已经读的从buffer中去掉,这时limit=capacity,position指向一个元素
cb.compact();
cb.flip();
while(cb.hasRemaining()) {
System.out.print(cb.get());
}
//重置buffer,position=0,limit=Capacity
cb.clear();
System.out.println(cb.position());
System.out.println(cb.limit());
}
}
第三、charset
public class CharsetTest {
public static void main(String[] args) {
//注意我们一般不会直接用Charset,需要转换字符编码可以用String,InputStreamReader,OutputSreamWriter;
Charset c = Charset.forName("gbk");
//下面这个bb已经是flip过后的结果了就不需要在flip了
ByteBuffer bb = c.encode("你好!中国!");
System.out.println(bb.position());
System.out.println(bb.limit());
System.out.println(bb.toString());
CharBuffer cb = c.decode(bb);
/*try {
System.out.println(new String(bb.array(),"utf8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}*/
}
}