最近復習計算機網絡,復習完應用層之后對于理論知識還是沒有一個深刻的概念,索性就動手用Java Socket API 模擬做一個HTTP服務器,鞏固一下應用層的知識。
HTTP基于TCP協議,協議采用了請求/響應模型。客戶端向服務器發送一個請求,請求頭包含請求的方法、URL、協議版本、以及包含請求修飾符、客戶信息和內容的類似于MIME的消息結構。服務器以一個狀態行作為響應,響應的內容包括消息協議的版本,成功或者錯誤編碼加上包含服務器信息、實體元信息以及可能的實體內容——百度百科。
話不多說,還是直接上圖。
具體字段這里不作解釋,不懂的請先自己了解http協議。這里主要是根據請求響應這一過程模擬HTTP服務器。
下面是代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
package com.example.httpserver; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class HttpServer { private static final Integer port = 80 ; //HTTP默認端口80 public static void main(String[] args) { ServerSocket serverSocket; try { //建立服務器Socket,監聽客戶端請求 serverSocket = new ServerSocket(port); System.out.println( "Server is running on port:" +serverSocket.getLocalPort()); //死循環不間斷監聽客戶端請求 while ( true ){ final Socket socket = serverSocket.accept(); System.out.println( "biuld a new tcp link with client,the cient address:" + socket.getInetAddress()+ ":" +socket.getPort()); //并發處理HTTP客戶端請求 service(socket); } } catch (IOException e) { e.printStackTrace(); } } public static void service(Socket socket) { new Thread(){ public void run(){ InputStream inSocket; try { //獲取HTTP請求頭 inSocket = socket.getInputStream(); int size = inSocket.available(); byte [] buffer = new byte [size]; inSocket.read(buffer); String request = new String(buffer); System.out.println( "ClientBrowser:\n" +request+ "\n" + "------------------------------------------------------------------" ); String firstLineOfRequest = "" ; String[] heads; String uri = "/index.html" ; String contentType = "" ; if (request.length() > 0 ){ firstLineOfRequest = request.substring( 0 ,request.indexOf( "\r\n" )); heads = firstLineOfRequest.split( " " ); uri = heads[ 1 ]; if (uri.indexOf( "html" ) != - 1 ){ contentType = "text/html" ; } else { contentType = "application/octet-stream" ; } } //將響應頭發送給客戶端 String responseFirstLine = "HTTP/1.1 200 OK\r\n" ; String responseHead = "Content-Type:" + contentType + "\r\n" ; OutputStream outSocket = socket.getOutputStream(); System.out.println( "ServerResponse:\n" +responseFirstLine+ "\n" +responseHead+ "\n" + "--------------------------------------------------------------------" ); outSocket.write(responseFirstLine.getBytes()); outSocket.write(responseHead.getBytes()); //通過HTTP請求中的uri讀取相應文件發送給客戶端 FileInputStream writehtml = new FileInputStream( new File( "wwwroot" +uri)); outSocket.write( "\r\n" .getBytes()); byte [] htmlbuffer = new byte [writehtml.available()]; if (writehtml != null ){ int len = 0 ; System.out.println( "writeHtml" ); while ((len = writehtml.read(htmlbuffer)) != - 1 ){ outSocket.write(htmlbuffer, 0 ,len); } } outSocket.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }.start(); } } |
代碼看注釋也很容易理解。現在我們在瀏覽器中輸入服務器地址+要訪問的文件
在看我們控制臺輸出的內容:
以上就是Java Socket 簡單的模擬HTTP服務器全過程。希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.jianshu.com/p/2ff10a02b2b8#