溫故而知新--day5
ip地址
IP是英文Internet Protocol的縮寫,意思是“網路之間互連的協議”,也就是為計算機網路相互連線進行通訊而設計的協議。當多個裝置要進行通訊的時候,ip地址必須唯一。
IP地址=網路地址+主機地址,(又稱:網路號和主機號組成)
網路號、主機號的確定需要“子網掩碼”
公網ip分類
- A類:該類IP地址的最前面為“1000”(1.0.0.0-126.0.0.0)(預設子網掩碼:255.0.0.0或 0xFF000000)
- B類:該類IP地址的最前面為“1100”(128.1.0.0-191.255.0.0)(預設子網掩碼:255.255.0.0或0xFFFF0000)
- C類:該類IP地址的最前面為“1110”(192.0.1.0-223.255.255.0)(子網掩碼:255.255.255.0或 0xFFFFFF00)
- D類:是多播地址。該類IP地址的最前面為“1110”,所以地址的網路號取值於224~239之間。一般用於多路廣播使用者。
- E類:是保留地址。該類IP地址的最前面為“1111”,所以地址的網路號取值於240~255之間。
私有地址
私有地址是不能直接在Internet網路中應用的,要上Internet的話要轉為公有地址。私有ip有以下幾種:
- A::10.0.0.0-10.255.255.255 即10.0.0.0/8
- B:172.16.0.0-172.31.255.255即172.16.0.0/12
- C:192.168.0.0-192.168.255.255 即192.168.0.0/16
子網掩碼
子網掩碼是用來判斷任意兩臺計算機的ip地址是否屬於同一子網路的根據。最為簡單的理解就是兩臺計算機各自的ip地址與子網掩碼進行and運算後,得出的結果是相同的,則說明這兩臺計算機是處於同一個子網路上的,可以進行直接的通訊。

圖中還可以寫成:192.168.1.1/24
24就是1的個數
埠
只使用ip地址進行通訊只能精確到某臺主機,因此加入了可以區別不同程式的識別符號:埠。
埠使用2個位元來表示,範圍為是0~25535。
埠分為兩種:
- 周知埠(Well Known Ports)
- 周知埠是眾所周知的埠號,範圍從0到1023,其中80埠分配給WWW服務,21埠分配給FTP服務等。
- 周知埠的監聽需要有root許可權。
- 動態埠(Dynamic Ports)
- 動態埠的範圍是從1024到65535。之所以稱為動態埠,是因為它一般不固定分配某種服務,而是動態分配。
更多見:
iso七層

socket
socket為套接字,是在應用層和傳輸層之間的一個抽象層,它把TCP/IP層複雜的操作抽象為幾個簡單的介面供應用層呼叫已實現程序在網路中通訊。socket是"開啟—讀/寫—關閉"模式的實現。
TCP
TCP/IP協議是Internet最基本的協議、Internet國際網際網路絡的基礎,由網路層的IP協議和傳輸層的TCP協議組成。
TCP協議就像打電話一樣,有“打-通話-掛”三個過程,“打”:是指客戶端與服務端建立連結(三次握手);“通話”:兩端進行通訊;“掛”:客戶端或服務端發起斷開請求。
注:seq:"sequance"序列號;ack:"acknowledge"確認號;SYN:"synchronize"請求同步標誌;;ACK:"acknowledge"確認標誌";FIN:"Finally"結束標誌。
在python中簡單使用TCP
參考tcp cs模型:
"""
服務端
"""
import socket
tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # SOCK_STREAM是tcp協議
# 繫結ip地址和監聽的埠
tcp_sock.bind(("", 8899)) # ip地址為空字串時,指的是本機
tcp_sock.listen(50) # 快取區大小
# 等待連結
new_sock, addr = tcp_sock.accept()
recv_data = new_sock.recv(1024) # 收
print(recv_data.decode())
new_sock.send(recv_data) # 發
# 關閉
new_sock.close()
tcp_sock.close()
"""
客戶端
"""
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 連線
s.connect(("127.0.0.1", 8899))
s.send(b"hello")
data = s.recv(1024)
print(data.decode())
s.close()
併發
上面這個簡單的例子只能簡單處理一個請求,要想同時處理多個請求,可以用一下方法實現:
多線(進)程
"""
服務端
""" import socket
from concurrent.futures import ThreadPoolExecutor def process_client(client, addr):
"""
處理過來的連結,進行收發處理
"""
try:
while True:
recv_data = client.recv(1024) # 收
print(recv_data.decode())
client.send(recv_data) # 發
finally:
# 關閉
client.close() def main(): tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcp_sock.bind(("", 8899)) # ip地址為空字串時,指的是本機
tcp_sock.listen(50) # 快取區大小 # 等待連結
try:
while True:
new_sock, addr = tcp_sock.accept()
with ThreadPoolExecutor(12) as t:
t.submit(process_client, new_sock, addr)
# 假如是多程序的話,此時應該加上 new_socke.close()
# 因為在使用多程序時,資源會再複製一份到另一程序
finally:
tcp_sock.close() if __name__ == '__main__':
main() """
客戶端
""" import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 連線
s.connect(("127.0.0.1", 8899)) while True:
data = input(">>>")
if not data:
continue
s.send(data.encode())
print(s.recv(1024).decode()) s.close()socketserver
python中除了有socket庫提供socket支援外,還有socketserver提供伺服器中心類,可以簡化網路伺服器的開發。
使用步驟:1、建立一個繼承socketserver.BaseRequestHandler的類
2、類中必須重寫一個名為handler的方法
3、例項化一個伺服器類,傳入伺服器的地址和請求處理程式類
4、呼叫serve_forever()事件迴圈監聽
注意:類中的self.request在TCP時為已連結的套接字物件;UDP時為(data, udp socket物件) 需要藉助self.client_address發資料
"""
服務端
""" import socketserver class MyServer(socketserver.BaseRequestHandler):
def handle(self) -> None:
print(self.client_address) # 地址
while True:
recv_data = self.request.recv(1024) # 收
# print(recv_data.decode())
self.request.send(recv_data) # 發 def main():
s = socketserver.ThreadingTCPServer(("", 8899), MyServer)
s.serve_forever() if __name__ == '__main__':
main()io多路複用
見day4的最後例子
UDP
無連線的、簡單的、面向資料包的傳輸層協議。
簡單收發例子
"""
服務端
"""
import socket
udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_sock.bind(("", 8899))
while True:
data, addr = udp_sock.recvfrom(1024)
print(data)
udp_sock.sendto(data, addr)
"""
客戶端
"""
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
data = input(">>>")
# 傳送訊息,資料+ip埠
s.sendto(data.encode(), ("127.0.0.1", 8899))
print(s.recvfrom(1024))
s.close()
udp廣播
要點:
- 傳送地址為
<broadcast>
- 設定socket選項
"""
udp廣播
局域內,只要監聽8899埠,都能收到訊息
""" import socket udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 傳送的地址
ip_port = ("<broadcast>", 8899)
# 修改socket選項, 固定格式
udp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
udp_sock.sendto(b"test", ip_port) while True:
recv_data = udp_sock.recvfrom(1024)
print(recv_data)
http
什麼是http協議
http協議是Hypertext Transfer Protocol --(超文字傳輸協議)的縮寫,在網際網路領域用得非常多的通訊協議。
HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端伺服器模型。HTTP是一個無狀態的協議。
HTTP協議是建立在TCP協議之上的一種應用。
1)在HTTP 1.0中,客戶端的每次請求都要求建立一次單獨的連線,在處理完本次請求後,就自動釋放連線。
2)在HTTP 1.1中,可以在一次連線中處理多個請求,並且多個請求可以重疊進行,不需要等待一個請求結束後再發送下一個請求。
http的過程
- 服務端監聽80埠,等待請求
- 客戶端(一般為瀏覽器)發起請求
- 服務端處理請求,返回資料
- 客戶端或服務端斷開連結
URI和URL
URI用字串標示某一網際網路資源,而URL表示資源的地點。可見URL是URI的子集。
URI要使用涵蓋全部必要資訊的URI、絕對URL以及相對URL。
相對URL是指從瀏覽器中基本URI處理的URL,來先看下URI的格式:
請求報文

POST /test/index.html HTTP/1.1
Accept: */*
Accept-Language: zh-cn
host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 12
Connection:close
sn=123&n=asa
響應報文
HTTP/1.1 200 OK
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:23:42 GMT
Content-Length:112
<html>
<head>
<title>HTTP響應示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>
請求方法
GET
伺服器將URL定位的資源放在響應報文的資料部分,回送給客戶端
利用?
在URL的結尾表示傳參,多個引數之間用&
隔開,如/index.html?id=10&op=bind
,傳遞引數長度受限制,且不適合傳送私密資料。POST
POST方法將請求引數封裝在HTTP請求資料中,以名稱/值的形式出現,可以傳輸大量資料。如請求報文哪裡的例子。HEAD
像GET,只不過服務端接受到HEAD請求後只返回響應頭,而不會發送響應內容。適用於檢視某個頁面的狀態。PUT
可用來傳輸檔案,就像FTP協議的檔案上傳一樣,要求在請求報文的主體中包含檔案內容,然後儲存到請求url指定的位置。由於put的方法不帶驗證機制,任何人都可以上傳檔案,存在安全性問題。DELETE
用來刪除檔案,是與put相反的方法,delete方法按照請求url刪除指定的資源。其本質和put方法一樣不帶驗證機制。
全部方法:
狀態碼
狀態程式碼由三位數字組成,第一個數字定義了響應的類別,且有五種可能取值。
1xx:指示資訊--表示請求已接收,繼續處理。
2xx:成功--表示請求已被成功接收、理解、接受。
3xx:重定向--要完成請求必須進行更進一步的操作。
4xx:客戶端錯誤--請求有語法錯誤或請求無法實現。
5xx:伺服器端錯誤--伺服器未能實現合法的請求。
常見狀態程式碼、狀態描述的說明如下。
200 OK:客戶端請求成功。
400 Bad Request:客戶端請求有語法錯誤,不能被伺服器所理解。
401 Unauthorized:請求未經授權,這個狀態程式碼必須和WWW-Authenticate報頭域一起使用。
403 Forbidden:伺服器收到請求,但是拒絕提供服務。
404 Not Found:請求資源不存在,舉個例子:輸入了錯誤的URL。
500 Internal Server Error:伺服器發生不可預期的錯誤。
503 Server Unavailable:伺服器當前不能處理客戶端的請求,一段時間後可能恢復正常,舉個例子:HTTP/1.1 200 OK(CRLF)。
cookie
Cookie是用於維持服務端會話狀態的,通常由服務端寫入,在後續請求中,供服務端讀取的一段文字。
cookie技術通過在請求和相應報文中寫入cookie資訊來控制客戶端的狀態。cookie會根據從服務端傳送的相應報文內的一個叫做set-cookie
的首部欄位資訊,通知客戶端儲存cookie。當下次客戶端再往伺服器傳送請求的時候,客戶端會自動在請求頭加入cookie值後傳送出去
更多:細說Cookie
session
Session是伺服器端使用的一種記錄客戶端狀態的機制,使用上比Cookie簡單一些,相應的也增加了伺服器的儲存壓力。
Session物件在客戶端第一次請求伺服器的時候建立。
更多:cookie和session的詳解與區別
https
詳見此文:HTTPS科普掃盲帖
websocket
【待完成】
擴充套件: