您好,登錄后才能下訂單哦!
用戶訪問網站流程
1.首先進行DNS解析
2.TCP/IP三次握手
3.http發送請求
4.大規模網站集群架構
5.http響應請求
6.TCP/IP四次揮手
wireshark抓包查看
這里沒有看到四次揮手,由于現在HTTP協議是長連接,HTTP請求頭中connection:keep-alive,即一次TCP連接,可進行多次HTTP請求
所以TCP連接沒有關閉。
1.用戶本地電腦輸入網址,例如www.163.com,首先查找本地DNS緩存,windows上可以在命令窗口執行ipconfig /displaydns查看。
2.本地DNS緩存中沒有,就查找本地hosts文件,查看是否有該域名對應的ip信息。
3.hosts文件中沒有找到,就去根DNS服務器查找,告知該域名屬于.com域服務器管理。
4.到.com服務器查找該域名對應的ip,告知歸163.com服務器管理。
5.到163.com服務器查找該域名對應的ip,找到了對應IP,返回給客戶端
6.客戶端接收返回的信息,把域名和IP對應信息保存到本地DNS緩存,同時請求該IP的服務器。
建立過程說明
1.由client發送建立TCP連接的請求報文,
其中包含seq序列號x-發送端隨機生成,
并且將報文中的SYN字段設置為1,表示需要建立TCP連接
2.server端回復client發送的TCP連接請求報文,
其中包含seq序列號y-由server端隨機生成,
并將SYN設置為1,
而且會產生Ack字段,是client端的序列號x+1,以便A收到信息時,知曉自己的TCP建立請求已經得到了驗證
3.client端接收到server端的驗證請求后,
回復序列號seq=x+1,
Ack=y+1
4.連接建立
包含請求起始行,請求頭,請求空行,請求體內容,后面詳細介紹
包含響應起始行,響應頭,響應空行,響應體內容,后面詳細介紹
斷開過程
1.client端發送斷開TCP連接請求,
其中包含序列號M,client端隨機生成,
Ack=N,
FIN設置為1,表示需要斷開TCP連接
2.server端回復請求,
其中包含序列號N,為client端發送的ack,
Ack=M+1,以便client端知曉自己的TCP斷開請求得到了驗證。
3.server端回復完client端的斷開請求后,不會馬上斷開連接,
server會先確保所有傳輸到client端的數據傳輸完成,
只要確認數據傳輸完成,
FIN設置為1,
并發送隨機序列號N,
Ack=M+1
4.client收到server的TCP斷開請求后,會回復server的斷開請求,
包含序列號=M+1,
Ack=N+1
5.server端接受到斷開請求,斷開連接。。
HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用于萬維網(WWW-World Wide Web)服務器與本地瀏覽器之間傳輸文本的傳送協議。
HTTP是一個屬于應用層的面向對象的協議,由于其簡捷、快速的方式,適用于分布式超媒體信息系統。
它在1990年提出,經過幾年的使用與發展,得到不斷的完善和擴展。
HTTP協議工作在客戶端--服務端框架。
瀏覽器作為HTTP客戶端,通過URL向HTTP服務端即web服務器發送請求。
Web服務器根據收到的請求,向客戶端發送響應信息。
1.是基于TCP/IP之上的應用層協議。
2.基于請求--響應模式
3.無連接協議
4.無狀態協議
http協議是基于TCP/IP協議之上的應用層協議。
HTTP協議規定,請求從客戶端發出,服務器端響應請求。
即請求是從客戶端開始建立的,服務端在沒有接收到請求時,不會發送響應信息。
HTTP是一種不保存狀態的協議。HTTP協議自身不對請求和響應之間的通信狀態進行保存。
即在HTTP級別,協議對于發送請求或響應都不做持久化處理。
使用HTTP協議,每當有新的請求發送時,就會有對應的響應產生。
協議本身不會保留之前的請求或響應報文信息。
這是為了更快的處理大量事務,確保協議的可伸縮性。
但是隨著web的發展,無狀態導致業務的處理出現問題。
例如用戶登錄購物網站,即使跳轉到了該網站的其他頁面,也需要保持登錄狀態。
為了保存用戶的狀態信息,HTTP/1.1引入了Cookie技術。
無連接的含義是限制每次連接只處理一個請求。
服務器處理完用戶的請求,并收到用戶的應答后,即斷開連接。
這種方式可以節省傳輸時間。
HTTP1.1是長連接,在請求頭中,connection:keep-alive,即一次TCP連接可以處理多個HTTP請求。
"請求方式:get與post請求"
1.GET提交的數據會放在URL之后,以?分隔URL與傳輸的數據,參數之間以&相連,如EditBook?name=test1&id=123456
POST會把數據放在請求體中。
2.GET請求的數據有大小限制(因為瀏覽器對URL的長度有限制),
POST提交的數據沒有大小限制。
3.GET與POST請求,在服務端獲取數據的方式不同。
1.IP----獨立IP數
獨立IP數是指不同IP地址的計算機訪問網站時,被統計的總次數。
由于在一個局域網中,訪問外部網站時,IP都是相同的,所以獨立IP數比實際的用戶數量要少很多
2.PV----Page View,即頁面瀏覽量或點擊量,
不管客戶端是否相同,IP是否相同,用于訪問一個頁面,就計算為一個PV。
3.UV----獨立訪客數,即Unique Visitor,同一個客戶端(PC或移動端)訪問網站被計為一個訪客。
一天(00:00-24:00)內相同的客戶端訪問一個網站,只計為一次UV。
cookie:標識用戶主機身份信息。
web應用程序是一種可以通過Web訪問的應用程序,程序的最大好處是用戶只需要瀏覽器即可。
應用程序有兩種模式,C/S、B/S。
C/S是客戶端/服務器端程序,B/S是瀏覽器/服務器端程序,這類程序一般借助于瀏覽器訪問。
web應用程序一般都是B/S模式。在網絡編程的意義下,瀏覽器是socket客戶端,服務器是socket服務端。
import socket
def server():
server_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_sock.bind(("127.0.0.1", 8800))
server_sock.listen(5)
while True:
# 一個連接關閉了,繼續接受下個連接
conn, client_addr = server_sock.accept()
data = conn.recv(1024)
print("recv_data-----", data)
# 發送數據到瀏覽器端
# \r\n\r\n表示響應體中的空行,表示響應頭內容結束。。這里是根據HTTP協議的要求,回復響應數據
conn.send("HTTP/1.1 200 OK\r\nstatus: 200\r\nContent-Type:text/html\r\n\r\n".encode("utf8"))
conn.send("<h2>Hello, vita!</h2>".encode("utf8"))
# 發送完數據,就關閉連接,因為HTTP協議是無連接的。
conn.close()
if __name__ == '__main__':
server()
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--默認不寫,是當前頁面的訪問地址-->
<form action=http://127.0.0.1:8800 method="post" target="_blank">
用戶名 <input type="text" name="user">
密碼 <input type="password" name="pwd">
<input type="submit">
</form>
</body>
</html>
上面我們演示了最簡單的web應用,是我們手動處理的接收HTTP請求,解析HTTP請求,發送HTTP響應。
如果我們自己來寫這些底層代碼,還沒開始寫動態HTML,就要花很多時間去讀HTTP規范。
正確的做法是底層代碼由專門的服務器軟件實現,我們用Python專注于生成HTML文檔。
因為我們不希望手動解析HTTP原始請求數據和設置相應響應格式,所以,需要一個統一的接口協議來實現這樣的服務器軟件,讓我們能夠專心用python編寫Web業務。
這個接口就是WSGI(web server gateway interface)。
wsgiref模塊就是python基于wsgi協議開發的服務模塊。
from wsgiref.simple_server import make_server
def application(environ,start_response):
# 按著HTTP協議解析數據:environ
# 按著http協議組裝數據:start_response
print(type(environ))
print(environ)
path = environ.get("PATH_INFO")
start_response('200 OK', [])
if path == "/login":
with open("login.html", "rb") as f:
data = f.read()
elif path == "/index":
with open("index.html", "rb") as f:
data = f.read()
# 第一次請求時,會請求該路徑,扇面演示我們已經看到,該路徑是Title旁邊的圖標
# 需要對該路徑的返回做個處理,否則會報錯
# 因為如果不做處理,data就沒有值,那么后面return [data]就會報data沒有定義的錯誤
elif path == "/favicon.ico":
# 這里是一個圖片
with open("favicon.ico", "rb") as f:
data = f.read()
return [data]
# make_server(host,port,app) app是回調函數
httpd = make_server("127.0.0.1",8800,application)
# 等待用戶連接:conn,addr=sock.accept()
httpd.serve_forever()
git地址 https://github.com/aawuliliaa/python-test/tree/master/excercise/9.Django/1.myWebStruct
main.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from wsgiref.simple_server import make_server
from urls import url_patterns
from views import *
def application(environ, start_response):
path = environ.get("PATH_INFO")
start_response("200 OK", [])
func = None
# url_patterns是一個列表,列表中的每項是一個數組
for item in url_patterns:
if path == item[0]:
func = item[1]
break
if func:
# 這種return []是wsgiref模塊規定的模式
return [func(environ)]
if __name__ == '__main__':
# 啟動socket服務,等待連接
httpd = make_server("127.0.0.1", 8800, application)
httpd.serve_forever()
models.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
import pymysql
def get_data(user,password):
conn = pymysql.connect(
host="10.0.0.61",
port=3306,
user="root",
password="123",
database='db1'
)
cur = conn.cursor()
sql = "select * from newuserinfo WHERE NAME ='%s' AND PASSWORD ='%s'" % (user, password)
cur.execute(sql)
return cur
urls.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from views import *
url_patterns=[
("/index", index),
("/login", login),
("/favicon.ico", favicon),
("/auth", auth)
]
views.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
from urllib.parse import parse_qs
from models import get_data
def index(environ):
with open("./templates/index.html","rb") as f:
data = f.read()
return data
def login(environ):
with open("./templates/login.html", "rb") as f:
data = f.read()
return data
def favicon(environ):
with open("./templates/favicon.ico", "rb") as f:
data = f.read()
return data
def auth(environ):
try:
request_body_size = int(environ.get('CONTENT_LENGTH', 0))
except (ValueError):
request_body_size = 0
request_body = environ['wsgi.input'].read(request_body_size)
data = parse_qs(request_body)
# 我這個是windows系統,所以這里要以gbk解碼,如果是linux或mac,要用utf8解碼
# 獲取頁面上的用戶名和密碼
user = data.get(b"user")[0].decode("gbk")
pwd = data.get(b"pwd")[0].decode("gbk")
cur = get_data(user, pwd)
# 如果用戶名,密碼正確,就展示index頁面
if cur.fetchone():
return index(environ)
else:
return b'user or pwd is wrong!'
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8800/auth" method="post" target="_blank">
用戶名 <input type="text" name="user">
密碼 <input type="text" name="pwd">
<input type="submit">
</form>
</body>
</html>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
index page
</body>
</html>
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。