利用NIO实现单文件的HTTP服务器
2016-10-31 21:51
218 查看
利用非阻塞IO实现的单文件HTTP服务器,可以在读取客户端通道数据的时候,分析客户端的请求数据,从而让服务器做出合理的响应,这部分在实现中省略了,为了展示出NIO服务器的一些基本实现形式。
package serverForNIO; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.URLConnection; 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.nio.charset.Charset; import java.util.Iterator; // 提供单文件的HTTP服务器,非阻塞 public class HYSingleFileHttpServerNIO { private int port = 1000; // 默认端口 private ByteBuffer contentBuffer; // 存储响应数据的缓冲区 public HYSingleFileHttpServerNIO(ByteBuffer data, String encoding, String MIMEType, int port) { this.port = port; // 无论是响应行,响应头,还是响应体,都转化成字节byte进行传送 String header = "HTTP/1.0 200 OK\r\n" + "Server: HYSingleFileHttpServerNIO\r\n" + "Content-length: " + data.limit() + "\r\n" + "Content-type: " + MIMEType + "\r\n\r\n"; byte[] headerData = header.getBytes(Charset.forName("UTF-8")); // 将响应行,响应头和响应体添加到缓冲区 ByteBuffer buffer = ByteBuffer.allocate(data.limit() + headerData.length); buffer.put(headerData); buffer.put(data); buffer.flip(); this.contentBuffer = buffer; } // 执行监听通道 public void run() throws IOException { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); ServerSocket serverSocket = serverSocketChannel.socket(); serverSocket.bind(new InetSocketAddress(InetAddress.getLocalHost(), port)); // 将通道设置为非阻塞 serverSocketChannel.configureBlocking(false); // 将通道注册到选择器上面 Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); // 监听器开始监听 while (true) { selector.select(); // 获取选择器筛选到满足条件的通道的key的集合 Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey key = (SelectionKey) keys.next(); // 删除迭代器当前指向的元素 keys.remove(); try { if (key.isAcceptable()) { // 服务器端通道时可接受状态,通过接收key获取服务器通道 // 通过服务器端通道的accept方法,获取请求的客户端通道 ServerSocketChannel server = (ServerSocketChannel)key.channel(); SocketChannel client = server.accept(); client.configureBlocking(false); client.register(selector, SelectionKey.OP_READ); } else if(key.isReadable()) { // 客户端通道准备好被读取 SocketChannel client = (SocketChannel)key.channel(); ByteBuffer buffer = ByteBuffer.allocate(4096); // 这里客户端一定要有数据传过来,不然服务器会一直阻塞 client.read(buffer); // 可以在读取客户端的请求数据后,HTTP服务器对读取到数据缓冲区的数据进行解析..... // 这里省略解析客户端数据的过程 // 将通道切换为只写模式(选择器会看key的通道是否满足写的条件) key.interestOps(SelectionKey.OP_WRITE); key.attach(contentBuffer.duplicate()); } else if(key.isWritable()) { SocketChannel client = (SocketChannel)key.channel(); ByteBuffer buffer = (ByteBuffer)key.attachment(); if (buffer.hasRemaining()) { client.write(buffer); } else { client.close(); } } } catch (Exception e) { // TODO: handle exception key.cancel(); try { key.channel().close(); } catch (Exception e2) { // TODO: handle exception } } } } } public static void main(String[] args) throws IOException { String contentType = URLConnection.getFileNameMap().getContentTypeFor("sources/index.html"); File file = new File("sources/index.html"); FileInputStream fileInputStream = new FileInputStream(file); byte[] data = new byte[4096]; fileInputStream.read(data); ByteBuffer byteBuffer = ByteBuffer.wrap(data); HYSingleFileHttpServerNIO singleFileHttpServerNIO = new HYSingleFileHttpServerNIO(byteBuffer, "UTF-8", contentType, 1000); singleFileHttpServerNIO.run(); } }
相关文章推荐
- 利用winInet实现文件上传到HTTP服务器
- NIO利用磁盘映射 实现的文件内容查找
- JSP利用组件实现文件上传的全攻略
- 利用资源文件实现对软件的保护
- 利用批处理文件和 vbs 脚本实现网站视频自动录制
- 利用文件属性结合Session实现在线人数统计
- 利用"流"实现exe文件的加密解密
- 利用ASP.NET服务器端自定义控件实现XML文件中还原表单
- 利用FTPClient类实现文件的上传下载功能
- 利用SharpZipLib实现压缩多个文件或整个目录
- windows下利用文件映射实现共享内存
- 利用VC++实现AVI文件的合成和分解
- 在struts1.1框架下,利用smartupload实现文件的上传(可以是多个文件)
- 利用计划任务和VBS脚本实现自动WEB共享文件夹里的文件
- [音视媒体制作][教程]利用tmpgenc实现rm,rmvb格式文件的VCD制作
- Delphi7 中利用Indy的TidFtp客户端控件实现在服务器指定目录下下载需要的文件
- VC下利用多线程实现文件的快速检索
- 为何不利用博客站的文件空间实现对ClickOnce的支持?
- 利用DirectShow实现对视频文件H264编码与解码基类
- 利用FTPClient类实现文件的上传下载功能