HTTP手記

 

---------------------tcp/ip模型和osi模型---------------------
tcp/ip協議模型   osi模型
應用層       應用層
        表示層
        會話層
傳輸層       傳輸層
網絡層       網絡層
鏈路層       數據鏈路層
        物理層css

---------------------交換機---------------------
一、網絡交換機介紹:
網絡交換機(又稱「網絡交換器」),是一個擴大網絡的器材,能爲子網絡中提供更多的鏈接端口,以便鏈接更多的計算機 具備性能價格比高、高度靈活、相對簡單、易於實現等特色 以太網技術已成爲當今最重要的一種局域網組網技術,網絡交換機也就成爲了最普及的交換機html

二、交換機的做用:
轉發過濾:當一個數據幀的目的地址在MAC地址表中有映射時,它被轉發到鏈接目的節點的端口而不是全部端口(如該數據幀爲廣播幀則轉發至全部端口)
學習功能:以太網交換機瞭解每一端口相連設備的MAC地址,並將地址同相應的端口映射起來存放在交換機緩存中的MAC地址表中瀏覽器

---------------------路由器---------------------
1. 路由器簡介
路由器(Router)又稱網關設備(Gateway)是用於鏈接多個邏輯上分開的網絡緩存

所謂邏輯網絡是表明一個單獨的網絡或者一個子網。當數據從一個子網傳輸到另外一個子網時,可經過路由器的路由功能來完成服務器

具備判斷網絡地址和選擇IP路徑的功能網絡

不在同一網段的pc,須要設置默認網關才能把數據傳送過去 一般狀況下,都會把路由器默認網關
當路由器收到一個其它網段的數據包時,會根據「路由表」來決定,把此數據包發送到哪一個端口;路由表的設定有靜態和動態方法

每通過一次路由器,那麼TTL值就會減一socket

---------------------模擬進行客戶端、DNS服務器、HTTP服務器實現---------------------tcp


---------------------HTTP請求的流程---------------------
步驟1:瀏覽器首先向服務器發送HTTP請求ide

方法:GET仍是POST,GET僅請求資源,POST會附帶用戶數據;函數

路徑:/full/url/path;

域名:由Host頭指定:Host: www.xxx.com

以及其餘相關的Header;

若是是POST,那麼請求還包括一個Body,包含用戶數據


步驟2:服務器向瀏覽器返回HTTP響應

響應代碼:200表示成功,3xx表示重定向,4xx表示客戶端發送的請求有錯誤,5xx表示服務器端處理時發生了錯誤;

響應類型:由Content-Type指定;

以及其餘相關的Header;

相應長度:由Content-Length:755

一般服務器的HTTP響應會攜帶內容,也就是有一個Body,包含響應的內容,網頁的HTML源碼就在Body中。


步驟3:若是瀏覽器還須要繼續向服務器請求其餘資源,好比圖片,就再次發出HTTP請求
Web採用的HTTP協議採用了很是簡單的請求-響應模式,從而大大簡化了開發。當咱們編寫一個頁面時,咱們只須要在HTTP請求中把HTML發送出去,不須要考慮如何附帶圖片、視頻等,瀏覽器若是須要請求圖片和視頻,它會發送另外一個HTTP請求,所以,一個HTTP請求只處理一個資源(此時就能夠理解爲TCP協議中的短鏈接,每一個連接只獲取一個資源,如須要多個就須要創建多個連接)

---------------------tcp協議三次握手和四次揮手---------------------

三次握手

四次握手

 

---------------------epoll和進程結合模擬實現一個簡單的http服務器---------------------

 

  1 #coding=utf-8
  2 
  3 #引用對應的數據包
  4 from socket import *
  5 
  6 import sys
  7 
  8 import re
  9 
 10 import select
 11 
 12 import multiprocessing
 13 
 14 from time import sleep
 15 
 16 #建立全局變量
 17 #建立一個epoll對象
 18 epoll=select.epoll()
 19 
 20 #建立兩個字典
 21 #字典1:根據套接字對應的文件標識符對應的套件字
 22 connection={}
 23 
 24 #字典2:根據套建字對應的文件表示符對應的ip和端口元祖信息
 25 address={}
 26 
 27 
 28 #運行進程
 29 def runProc(recvData,soc,addr,fd):
 30     #引用全局變量進行處理
 31     global epoll
 32     global connection
 33     global address
 34     
 35     #使用正則,獲取到對應的要讀取的文件名
 36     fileName=re.search("GET (.*) HTTP",recvData).group(1)
 37     
 38     print(fileName)
 39 
 40     #調用函數獲取處處理後的地址
 41     fileName=getPath(fileName)
 42 
 43     #獲取文件後綴名,進行相應頭文件的準備
 44     fileExt=fileName[fileName.rindex('.')+1:]
 45 
 46     print ("02-文件的後綴名--:"+fileExt)
 47     
 48     #存儲響應報文
 49     httpHead=''
 50 
 51     if fileExt.lower() in ['html','css']:
 52         #制定文件的讀取操做
 53         fil=open(fileName,'r')
 54 
 55         #讀取制定文件中的數據信息
 56         htmlText=fil.read()
 57 
 58         #關閉對應的文件對象
 59         fil.close()
 60 
 61         #建立變量:存儲有效的響應頭文件
 62         httpHead="HTTP/1.1 200 OK \r\n Content-Type:text/"+fileExt.lower()+" \r\n\r\n"
 63         #進行數據的回覆操做
 64         soc.send(httpHead+htmlText)
 65 
 66         #將該套接字從epoll中註銷
 67         epoll.unregister(fd)
 68 
 69         #從字典中進行排除
 70         del connection[fd]
 71         del address[fd]
 72 
 73         soc.close()
 74 
 75         print("%s-------end"%fileExt)
 76 
 77     elif fileExt.lower() in ['png','jpg','gif']:
 78         #制定文件的讀取操做
 79         fil=open(fileName,'rb')
 80 
 81         #讀取制定文件中的數據信息
 82         htmlText=fil.read()
 83 
 84         #關閉對應的文件對象
 85         fil.close()
 86         httpHead="HTTP/1.1 200 ok \r\n Content-Type:image/"+fileExt.lower()+" \r\n\r\n"
 87         
 88         #print(fileExt.lower())
 89         #print(htmlText)
 90         
 91         #sleep(2)
 92 
 93         #進行數據的回覆操做
 94         soc.send(httpHead+htmlText)
 95 
 96         #將該套接字從epoll中註銷
 97         epoll.unregister(fd)
 98 
 99         #從字典中進行排除
100         del connection[fd]
101         del address[fd]
102 
103         soc.close()
104 
105         print("%s------end"%fileExt.lower())
106 
107 
108 #函數:文件路徑
109 def getPath(fileName):
110     #變量存儲文件地址;
111     filePath=''
112     
113     print(fileName)
114 
115     #根目錄,默認指向./html/Index.html
116     if fileName[0:4]=='/html':
117         filePath='.'+fileName                    
118     else:
119         filePath='./html'+fileName
120     
121     print("01-獲取到對應的文件路徑--:%s"%filePath)
122 
123     return filePath
124 
125 #主函數
126 def main():
127     #引用全局變量進行處理
128     global epoll
129     global connection
130     global address
131     
132     #建立服務器套接字
133     tcpSerSoc=socket(AF_INET,SOCK_STREAM)
134 
135     tcpSerSoc.setsockopt(SOL_SOCKET, SO_REUSEADDR,1)
136 
137     #進行對應數據的綁定
138     tcpSerSoc.bind(("",int(sys.argv[1])))
139 
140     #tcp服務器開啓被動監聽狀態
141     tcpSerSoc.listen(10)
142 
143     #使用epoll對服務器套接字在操做系統中進行註冊
144     epoll.register(tcpSerSoc.fileno(),select.EPOLLIN|select.EPOLLET)
145 
146     #提示開啓對應的服務
147     print("-----開啓對應的HTTP服務-----")
148 
149     #循環,對客戶端傳遞過來的數據進行處理
150     while True:
151         #經過操做系統獲取到要進行數據處理的套接字
152         epollList=epoll.poll()
153 
154         #遍歷全部的套接字進行相應的處理
155         for fd,event in epollList:
156             #判斷是否爲服務器的套接字
157             if fd==tcpSerSoc.fileno():        
158                 #接收客戶端對應的數據信息
159                 newSocket,destAddr= tcpSerSoc.accept()
160     
161                 print("客戶端(%s)以接入HTTP服務器"%str(destAddr))
162                 
163                 #將對應的數據向字典中進行存儲
164                 connection[newSocket.fileno()]=newSocket
165                 address[newSocket.fileno()]=destAddr
166 
167                 #將新的套接字經過epoll向操做系統中進行註冊
168                 epoll.register(newSocket.fileno(),select.EPOLLIN|select.EPOLLET)
169 
170             elif event==select.EPOLLIN:
171                 #拿到對應的套接字和ip端口
172                 soc=connection[fd]
173                 addr=address[fd]
174 
175                 #進行客戶端數據對應的接收操做
176                 recvData=soc.recv(1024)
177 
178                 #判斷接受的數據是否爲空:若是爲空表示客戶下線
179                 if len(recvData)>0:
180                     #啓動一個新的socked進程
181                     p=multiprocessing.Process(target=runProc,args=(recvData,soc,addr,fd))
182                     p.start()
183                     p.join()
184                     
185                     soc.close()
186                 else:
187                     
188                     print("客戶(%s)以離開"%str(addr))
189 
190                     #將該套接字從epoll中註銷
191                     epoll.unregister(fd)
192 
193                     soc= connection[fd]
194 
195                     #從字典中進行排除
196                     del connection[fd]
197                     del address[fd]
198 
199                     #關閉該套接字
200                     soc.close()
201                                     
202     #關閉服務器套接字
203     tcpSerSoc.close()
204 
205 
206 #程序入口
207 if __name__=='__main__':
208     main()
epoll和進程實現簡單的HTTP服務器
相關文章
相關標籤/搜索