实现HTTP协议

package com.test1;

import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.util.Iterator;

public class HttpServer {
    public static void main(String[] args) throws Exception{
        //创建ServerSocketChannel,监听8082端口
        ServerSocketChannel ssc=ServerSocketChannel.open();
        ssc.socket().bind(new InetSocketAddress(8082));

        //设置为非阻塞模式
        ssc.configureBlocking(false);
        //为ssc注册选择器
        Selector selector=Selector.open();
        ssc.register(selector, SelectionKey.OP_ACCEPT);
        //创建处理器
        while(true) {
            //等待请求,每次等待阻塞3s,超过3s后线程继续向下运行,如果传入0或者不传参数将一直阻塞
            if(selector.select(3000)==0) {
                continue;
            }
            //获取待处理的SelectionKey
            Iterator<SelectionKey> keyIter=selector.selectedKeys().iterator();

            while(keyIter.hasNext()) {
                SelectionKey key=keyIter.next();

                //启动新线程处理SelectionKey
                new Thread(new HttpHandler(key)).run();
                //处理完后,从待处理的SelectionKey迭代器中移除当前所使用的key
                keyIter.remove();

            }
        }

    }


}
package com.test1;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;


public class HttpHandler implements Runnable{
    private int bufferSize=1024;
    private String localCharset="UTF-8";
    public SelectionKey key;
    public HttpHandler(SelectionKey key) {  
        this.key=key;
    }

    public void handleAccept() throws IOException{
        SocketChannel sc=((ServerSocketChannel) key.channel()).accept();
        sc.configureBlocking(false);
        sc.register(key.selector(), SelectionKey.OP_READ,ByteBuffer.allocate(bufferSize));

    }
    public void handleRead(SelectionKey key) throws IOException{
        SocketChannel clientChannel=(SocketChannel) key.channel();
        clientChannel.configureBlocking(false);
        clientChannel.register(key.selector(), SelectionKey.OP_READ,ByteBuffer.allocate(bufferSize));
    }
    public void handleRead() throws IOException{
        //获取channel
        SocketChannel sc=(SocketChannel) key.channel();
        //获取buffer并重置
        ByteBuffer buffer=(ByteBuffer) key.attachment();
        buffer.clear();
        //没有读到内容则关闭
        if(sc.read(buffer)==-1) {
            sc.close();
            }else {
                //接收请求数据
                buffer.flip();
                String receivedString =Charset.forName(localCharset).newDecoder().decode(buffer).toString();

                //控制台打印请求报文头
                String[] requestMessge=receivedString.split("\r\n");
                for(String s:requestMessge) {
                    System.out.println(s);
                    //遇到空行说明报文头已经打印完
                    if(s.isEmpty()) {
                        break;
                    }

                    //控制台打印首行信息
                    String[] firstLine=requestMessge[0].split("");
                    System.out.println();
                    System.out.println("Methid:\t"+firstLine[0]);
                    System.out.println("url:\t"+firstLine[1]);
                    System.out.println("HTTP Version:\t"+firstLine[2]);
                    System.out.println();

                    //返回客户端
                    StringBuilder sendString =new StringBuilder();
                    sendString.append("HTTP/1.1 200 Ok\r\n");//响应报文首行,200表示处理成功
                    sendString.append("localCharset"+localCharset+"\r\n");
                    sendString.append("\r\n");//报文结束后加一个空行

                    sendString.append("<html><head><title>显示报文</title></head><body>");
                    sendString.append("接收到请求报文是:<br/>");
                    for(String s1:requestMessge) {
                        sendString.append(s1+"<br/>");
                    }
                    sendString.append("<body></html>");
                    buffer=ByteBuffer.wrap(sendString.toString().getBytes(localCharset));
                    sc.write(buffer);
                    sc.close();
                }
            }

    }
    public void run() {
        //接收到连接请求时
        try {
            if (key.isAcceptable()) {
                handleAccept();
            }
            if (key.isReadable()) {
                handleRead();
            } 
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }

    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值