package com.what21.httpserver.nio;
import java.net.InetSocketAddress;
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 MyHttpServer {
/**
* 启动服务
*
* @param port
* @throws Exception
*/
public static void startServer(int port)throws Exception {
// 创建选择器
Selector selector = Selector.open();
// 打开监听信道
ServerSocketChannel server = ServerSocketChannel.open();
// 与本地端口绑定
server.socket().bind(new InetSocketAddress(port));
// 设置为非阻塞模式
server.configureBlocking(false);
// 非阻塞信道才能够注册选择器,在注册过程中指出该信道可以进行Accept操作
SelectionKey serverkey = server.register(selector,SelectionKey.OP_ACCEPT);
// 反复循环,等待IO
while (true) {
// 取到选择器的监听事件
selector.select();
// 取到通道内监听事件的集合
Set keys = selector.selectedKeys();
// 遍历监听事件
for (Iterator it = keys.iterator(); it.hasNext();) {
SelectionKey key = (SelectionKey) it.next();
//移出此事件
it.remove();
if (key == serverkey) {
if (key.isAcceptable()) {
// 取到对应的SocketChannel
SocketChannel client = server.accept();
if (client == null){
continue;
}
client.configureBlocking(false);
// 在此通道上注册事件
client.register(selector,SelectionKey.OP_READ);
}
} else {
// 处理{@link SelectionKey#OP_READ}事件
SocketChannel client = (SocketChannel) key.channel();
if (!key.isReadable()){
continue;
}
key.cancel();
new MyHandler(client).start();
}
}
}
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
startServer(8000);
}
}
package com.what21.httpserver.nio;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
public class MyHandler extends Thread {
// 编码
static CharsetEncoder encoder = Charset.forName("GBK").newEncoder();
private SocketChannel client;
public MyHandler(SocketChannel client){
this.client = client;
}
@Override
public void run() {
try {
//==============================请求处理开始==============================
ByteBuffer buffer = ByteBuffer.allocate(1024);
client.read(buffer);
// 将缓冲区准备为数据传出状态
buffer.flip();
CharsetDecoder decoder = Charset.forName("GBK").newDecoder();
String rquestStr= decoder.decode(buffer).toString();
System.out.println(rquestStr);
//==============================响应处理开始==============================
String html = "HI~ , My HTTP Server!
";
// 响应头
StringBuilder sb = new StringBuilder();
sb.append("HTTP/1.0 200 OK").append("\r\n");
sb.append("MIME_version:1.0").append("\r\n");
sb.append("Content_Type:text/html").append("\r\n");
sb.append("Content_Length:" + html.length()).append("\r\n");
sb.append("\r\n");
// 响应内容
sb.append(html).append("\r\n");
sb.append("\r\n");
buffer=ByteBuffer.wrap(sb.toString().getBytes());
client.write(buffer);
} catch (Exception e) {
e.printStackTrace();
} finally{
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}