77import java .nio .channels .AsynchronousSocketChannel ;
88import java .nio .channels .CompletionHandler ;
99import java .nio .charset .StandardCharsets ;
10+ import java .time .ZonedDateTime ;
11+ import java .time .format .DateTimeFormatter ;
12+ import java .time .ZoneId ;
1013import java .util .concurrent .ThreadFactory ;
1114
1215import com .alibaba .fastjson .JSON ;
@@ -26,31 +29,29 @@ public class HttpServer {
2629
2730 public static void main (String [] args ) throws Exception {
2831
29- // 创建通道提供者,false 表示非低内存模式
32+ // 创建异步通道提供者
3033 EnhanceAsynchronousChannelProvider provider = new EnhanceAsynchronousChannelProvider (false );
3134
32- // 创建一个异步通道组,线程数设为2(根据需求调整)
35+ // 创建通道组
3336 AsynchronousChannelGroup group = provider .openAsynchronousChannelGroup (2 , new ThreadFactory () {
3437 @ Override
3538 public Thread newThread (Runnable r ) {
3639 return new Thread (r , "http-server-thread" );
3740 }
3841 });
3942
40- // 使用提供者创建服务器通道
43+ // 创建服务器通道并绑定端口
4144 EnhanceAsynchronousServerSocketChannel server = (EnhanceAsynchronousServerSocketChannel ) provider .openAsynchronousServerSocketChannel (group );
42- // 绑定端口,例如 80,设置 backlog
4345 server .bind (new InetSocketAddress (8080 ), 0 );
4446
4547 System .out .println ("HTTP Server 正在监听端口 8080 ..." );
4648
47- // 异步接受连接请求
49+ // 异步接受连接
4850 server .accept (null , new CompletionHandler <AsynchronousSocketChannel , Object >() {
4951 @ Override
5052 public void completed (AsynchronousSocketChannel channel , Object attachment ) {
51- // 接收到连接后,立即继续接受下一个连接
53+ // 继续接收其他连接
5254 server .accept (null , this );
53- // 处理客户端连接
5455 handleClient (channel );
5556 }
5657
@@ -60,16 +61,14 @@ public void failed(Throwable exc, Object attachment) {
6061 }
6162 });
6263
63- // 主线程阻塞,以保证服务器运行
64+ // 主线程阻塞
6465 Thread .currentThread ().join ();
6566 }
6667
6768 private static void handleClient (AsynchronousSocketChannel channel ) {
68- // 通过 BufferPage 池化获取一个 VirtualBuffer,分配 8192 字节空间
6969 VirtualBuffer virtualBuffer = bufferPage .allocate (8192 );
7070 ByteBuffer buffer = virtualBuffer .buffer ();
7171
72- // 异步读取客户端请求,将 VirtualBuffer 作为附件传入
7372 channel .read (buffer , virtualBuffer , new CompletionHandler <Integer , VirtualBuffer >() {
7473 @ Override
7574 public void completed (Integer result , VirtualBuffer attachment ) {
@@ -78,25 +77,42 @@ public void completed(Integer result, VirtualBuffer attachment) {
7877 buffer .flip ();
7978 byte [] bytes = new byte [buffer .remaining ()];
8079 buffer .get (bytes );
81- // 将请求转换成字符串进行判断
8280 String request = new String (bytes , StandardCharsets .UTF_8 );
83-
81+
82+ // 生成当前时间,格式为 RFC 1123 格式
83+ String date = DateTimeFormatter .RFC_1123_DATE_TIME .format (ZonedDateTime .now (ZoneId .of ("GMT" )));
84+
8485 ByteBuffer responseBuffer ;
85- // 如果请求以 "GET /plaintext" 开头,则直接返回 HELLO_WORLD_BYTES
8686 if (request .startsWith ("GET /plaintext" )) {
87- String httpResponse = "HTTP/1.1 200 OK\r \n " + "Content-Length: 13\r \n " + "Server: aio-socket\r \n " + "Content-Type: text/plain\r \n " + "\r \n " + "Hello, World!" ;
87+ String body = "Hello, World!" ;
88+ String httpResponse = "HTTP/1.1 200 OK\r \n " +
89+ "Content-Length: " + body .getBytes (StandardCharsets .UTF_8 ).length + "\r \n " +
90+ "Server: aio-socket\r \n " +
91+ "Content-Type: text/plain\r \n " +
92+ "Date: " + date + "\r \n " +
93+ "\r \n " +
94+ body ;
8895 responseBuffer = ByteBuffer .wrap (httpResponse .getBytes (StandardCharsets .UTF_8 ));
8996
9097 } else if (request .startsWith ("GET /json" )) {
9198 String jsonString = JSON .toJSONString (new Message (HELLO_WORLD ));
92- int length = jsonString .length ();
93- String httpResponse = "HTTP/1.1 200 OK\r \n " + "Content-Length: " + length + "\r \n " + "Server: aio-socket\r \n " + "Content-Type: application/json\r \n " + "\r \n " + jsonString ;
94-
99+ int length = jsonString .getBytes (StandardCharsets .UTF_8 ).length ;
100+ String httpResponse = "HTTP/1.1 200 OK\r \n " +
101+ "Content-Length: " + length + "\r \n " +
102+ "Server: aio-socket\r \n " +
103+ "Content-Type: application/json\r \n " +
104+ "Date: " + date + "\r \n " +
105+ "\r \n " +
106+ jsonString ;
95107 responseBuffer = ByteBuffer .wrap (httpResponse .getBytes (StandardCharsets .UTF_8 ));
96-
97108 } else {
98- // 默认返回完整的 HTTP 响应
99- String httpResponse = "HTTP/1.1 200 OK\r \n " + "Content-Length: 13\r \n " + "Content-Type: text/plain\r \n " + "\r \n " + "Hello, World!" ;
109+ String body = "Hello, World!" ;
110+ String httpResponse = "HTTP/1.1 200 OK\r \n " +
111+ "Content-Length: " + body .getBytes (StandardCharsets .UTF_8 ).length + "\r \n " +
112+ "Content-Type: text/plain\r \n " +
113+ "Date: " + date + "\r \n " +
114+ "\r \n " +
115+ body ;
100116 responseBuffer = ByteBuffer .wrap (httpResponse .getBytes (StandardCharsets .UTF_8 ));
101117 }
102118
@@ -109,7 +125,6 @@ public void completed(Integer result, VirtualBuffer attachment) {
109125 } catch (IOException e ) {
110126 e .printStackTrace ();
111127 } finally {
112- // 写完响应后归还虚拟缓冲区
113128 attachment .clean ();
114129 }
115130 }
@@ -122,13 +137,11 @@ public void failed(Throwable exc, VirtualBuffer attachment) {
122137 } catch (IOException e ) {
123138 e .printStackTrace ();
124139 } finally {
125- // 出现写异常时也归还虚拟缓冲区
126140 attachment .clean ();
127141 }
128142 }
129143 });
130144 } else {
131- // 未读到数据,则关闭连接
132145 try {
133146 channel .close ();
134147 } catch (IOException e ) {
@@ -137,7 +150,6 @@ public void failed(Throwable exc, VirtualBuffer attachment) {
137150 }
138151 } finally {
139152 // 注意:如果在写操作中已经归还了虚拟缓冲区,则不要重复释放
140- // attachment.clean();
141153 }
142154 }
143155
0 commit comments