---------------------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()