一HTTP協議的作用原理
WWW是以Internet作為傳輸媒介的一個應用系統WWW網上最基本的傳輸單位是Web網頁WWW的工作基於客戶機/服務器計算模型由Web 浏覽器(客戶機)和Web服務器(服務器)構成兩者之間采用超文本傳送協議(HTTP)進行通信HTTP協議是基於TCP/IP協議之上的協議是Web浏覽器和Web服務器之間的應用層協議是通用的無狀態的面向對象的協議HTTP協議的作用原理包括四個步驟
() 連接Web浏覽器與Web服務器建立連接打開一個稱為socket(套接字)的虛擬文件此文件的建立標志著連接建立成功
() 請求Web浏覽器通過socket向Web服務器提交請求HTTP的請求一般是GET或POST命令(POST用於FORM參數的傳遞)GET命令的格式為
GET 路徑/文件名 HTTP/
文件名指出所訪問的文件HTTP/指出Web浏覽器使用的HTTP版本
() 應答Web浏覽器提交請求後通過HTTP協議傳送給Web服務器Web服務器接到後進行事務處理處理結果又通過HTTP傳回給Web浏覽器從而在Web浏覽器上顯示出所請求的頁面
例假設客戶機與/mydir/l建立了連接就會發送GET命令GET /mydir/l HTTP/主機名為的Web服務器從它的文檔空間中搜索子目錄mydir的文件l如果找到該文件Web服務器把該文件內容傳送給相應的Web浏覽器
為了告知 Web浏覽器傳送內容的類型Web服務器首先傳送一些HTTP頭信息然後傳送具體內容(即HTTP體信息)HTTP頭信息和HTTP體信息之間用一個空行分開
常用的HTTP頭信息有
① HTTP OK
這是Web服務器應答的第一行列出服務器正在運行的HTTP版本號和應答代碼代碼 OK表示請求完成
② MIME_Version
它指示MIME類型的版本
③ content_type類型
這個頭信息非常重要它指示HTTP體信息的MIME類型如content_typetext/html指示傳送的數據是HTML文檔
④ content_length長度值
它指示HTTP體信息的長度(字節)
() 關閉連接當應答結束後Web浏覽器與Web服務器必須斷開以保證其它Web浏覽器能夠與Web服務器建立連接
二Java實現Web服務器功能的程序設計
根據上述HTTP協議的作用原理實現GET請求的Web服務器程序的方法如下
() 創建ServerSocket類對象監聽端口這是為了區別於HTTP的標准TCP/IP端口而取的
() 等待接受客戶機連接到端口得到與客戶機連接的socket
() 創建與socket字相關聯的輸入流instream和輸出流outstream
() 從與socket關聯的輸入流instream中讀取一行客戶機提交的請求信息請求信息的格式為GET 路徑/文件名 HTTP/
() 從請求信息中獲取請求類型如果請求類型是GET則從請求信息中獲取所訪問的HTML文件名沒有HTML文件名時則以l作為文件名
() 如果HTML文件存在則打開HTML文件把HTTP頭信息和HTML文件內容通過socket傳回給Web浏覽器然後關閉文件否則發送錯誤信息給Web浏覽器
() 關閉與相應Web浏覽器連接的socket字
下面的程序是根據上述方法編寫的可實現多線程的Web服務器以保證多個客戶機能同時與該Web服務器連接
程序WebServerjava文件
//WebServerjava 用JAVA編寫Web服務器
import javaio*
import *
public class WebServer {
public static void main(String args[]) {
int i= PORT=
ServerSocket server=null
Socket client=null
try {
server=new ServerSocket(PORT)
Systemoutprintln(Web Server is listening on port +servergetLocalPort())
for () {client=serveraccept() //接受客戶機的連接請求
new ConnectionThread(clienti)start()
i++
}
} catch (Exception e) {Systemoutprintln(e)}
}
}
/* ConnnectionThread類完成與一個Web浏覽器的通信 */
class ConnectionThread extends Thread {
Socket client //連接Web浏覽器的socket字
int counter //計數器
public ConnectionThread(Socket clint c) {
client=cl
counter=c
}
public void run() //線程體
{try {
String destIP=clientgetInetAddress()toString() //客戶機IP地址
int destport=clientgetPort() //客戶機端口號
Systemoutprintln(Connection +counter+connected to +destIP+ on port +destport+)
PrintStream outstream=new PrintStream(clientgetOutputStream())
DataInputStream instream=new DataInputStream(clientgetInputStream())
String inline=instreamreadLine() //讀取Web浏覽器提交的請求信息
Systemoutprintln(Received+inline)
if (getrequest(inline)) { //如果是GET請求
String filename=getfilename(inline)
File file=new File(filename)
if (fileexists()) { //若文件存在則將文件送給Web浏覽器
Systemoutprintln(filename+ requested)
outstreamprintln(HTTP/ OK)
outstreamprintln(MIME_version)
outstreamprintln(Content_Typetext/html)
int len=(int)filelength()
outstreamprintln(Content_Length+len)
outstreamprintln()
sendfile(outstreamfile) //發送文件
outstreamflush()
} else { //文件不存在時
String notfound=
Error file not found
outstreamprintln(HTTP/ no found)
outstreamprintln(Content_Typetext/html)
outstreamprintln(Content_Length+notfoundlength()+)
outstreamprintln()
outstreamprintln(notfound)
outstreamflush()
}
}
long m=
while (m<) {m++} //延時
clientclose()
} catch (IOException e) {
Systemoutprintln(Exception+e)
}
}
/* 獲取請求類型是否為GET */
boolean getrequest(String s) {
if (slength()>)
{if (ssubstring()equalsIgnoreCase(GET)) return true
}
return false
}
/* 獲取要訪問的文件名 */
String getfilename(String s) {
String f=ssubstring(sindexOf(′ ′)+)
f=fsubstring(findexOf(′ ′))
try {
if (fcharAt()==′/′)
f=fsubstring()
} catch (StringIndexOutOfBoundsException e) {
Systemoutprintln(Exception+e)
}
if (fequals()) f=l
return f
}
/*把指定文件發送給Web浏覽器 */
void sendfile(PrintStream outsFile file) {
try {
DataInputStream in=new DataInputStream(new FileInputStream(file))
int len=(int)filelength()
byte buf[]=new byte[len]
inreadFully(buf)
outswrite(buflen)
outsflush()
inclose()
} catch (Exception e) {
Systemoutprintln(Error retrieving file)
Systemexit()
}
}
}
程序中的ConnectionThread線程子類用來分析一個Web浏覽器提交的請求並將應答信息傳回給Web浏覽器其中getrequest()方法用來檢測客戶的請求是否為GETgetfilename(s)方法是從客戶請求信息s中獲取要訪問的HTML文件名sendfile()方法把指定文件內容通過socket傳回給Web浏覽器
對上述程序的getrequest()方法和相關部分作修改也能對POST請求進行處理
三運行實例
為了測試上述程序的正確性將編譯後的WebServerclassConnectionThreadclass和下面的l文件置於網絡的某台主機的同一目錄中(如主機NTSRV的CJWEB目錄)
程序l文件
這是用JAVA寫出的WEB服務器主頁
年月日
首先在該主機上用java命令運行WebServerclass
Cjweb>java webserver
然後在客戶機運行浏覽器軟件在URL處輸入WebServer程序所屬的URL地址(如)就在浏覽器窗口顯示出指定的HTML文檔
注意不能缺省端口號如缺省則運行該主機的正常WEB服務器
說明不具備網絡條件的可在安裝了Windows 的單機上進行測試方法是用localhost或代替URL地址的域名部分即URL地址為
From:http://tw.wingwit.com/Article/program/Java/hx/201311/26626.html