python環(huán)境下的tcp網(wǎng)絡(luò)編程
網(wǎng)絡(luò)概念
網(wǎng)絡(luò)是由節(jié)點和連線構(gòu)成,表示諸多對象及其相互聯(lián)系梯皿。在數(shù)學(xué)上仇箱,網(wǎng)絡(luò)是一種圖,一般認(rèn)為專指加權(quán)圖东羹。網(wǎng)絡(luò)除了數(shù)學(xué)定義外剂桥,還有具體的物理含義,即網(wǎng)絡(luò)是從某種相同類型的實際問題中抽象出來的模型属提。在計算機領(lǐng)域中权逗,網(wǎng)絡(luò)是信息傳輸、接收冤议、共享的虛擬平臺斟薇,通過它把各個點、面恕酸、體的信息聯(lián)系到一起堪滨,從而實現(xiàn)這些資源的共享。
客戶端/服務(wù)端
1.在計算機中尸疆,客戶端和服務(wù)端的架構(gòu)模式椿猎,區(qū)分為硬件模式和軟件模式
- 硬件客戶端
客戶端(Client)或稱為用戶端,是指與服務(wù)器相對應(yīng)寿弱,為客戶提供本地服務(wù)的程序犯眠。除了一些只在本地運行的應(yīng)用程序之外,一般安裝在普通的客戶機上症革,需要與服務(wù)端互相配合運行筐咧。因特網(wǎng)發(fā)展以后,較常用的用戶端包括了如萬維網(wǎng)使用的網(wǎng)頁瀏覽器,收寄電子郵件時的電子郵件客戶端量蕊,以及即時通訊的客戶端軟件等铺罢。對于這一類應(yīng)用程序,需要網(wǎng)絡(luò)中有相應(yīng)的服務(wù)器和服務(wù)程序來提供相應(yīng)的服務(wù)残炮,如數(shù)據(jù)庫服務(wù)韭赘,電子郵件服務(wù)等等,這樣在客戶機和服務(wù)器端势就,需要建立特定的通信連接泉瞻,來保證應(yīng)用程序的正常運行。 - 服務(wù)端
服務(wù)端是為客戶端服務(wù)的苞冯,服務(wù)的內(nèi)容諸如向客戶端提供資源袖牙,保存客戶端數(shù)據(jù)。 - 軟件客戶端/服務(wù)端
軟件服務(wù)器和硬件服務(wù)器不同的是:軟件服務(wù)器是安裝在硬件上的一種特殊的軟件舅锄,可以通 過程序的執(zhí)行完成數(shù)據(jù)檢索鞭达、數(shù)據(jù)處理、數(shù)據(jù)存取等等各種特性皇忿,再通過網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)的共享通信畴蹭,完成提供網(wǎng)絡(luò)數(shù)據(jù)服務(wù)的功能!
IP&PORT
- IP: internet protocal 網(wǎng)絡(luò)互聯(lián)協(xié)議禁添,中文縮寫:網(wǎng)協(xié)撮胧;英文縮寫:IP
- PORT:端口 在通過 IP 地址確定了網(wǎng)絡(luò)上的某個具體主機之后桨踪,具體的數(shù)據(jù)通信主要是通過工作在計算 機中的軟件執(zhí)行的老翘。
- 計算機中的端口號的范圍是 0~65535 之間
端口號根據(jù)其使用場景,一般區(qū)分為公用端口锻离、動態(tài)端口铺峭、保留端口
公用端口:0~1023
動態(tài)端口:1024~65535
保留端口:一般是 unix 系統(tǒng)中超級用戶進(jìn)程分配保留端口號
協(xié)議
協(xié)議:英文名稱 protocal,是多方協(xié)商計議之后得出的約定汽纠、規(guī)則卫键、規(guī)范 (ps:不是強制約定的)
通常情況下為了讓工作在網(wǎng)絡(luò)中的多臺計算機之間能友好的完成不同軟件的數(shù)據(jù)的通信,出現(xiàn)了互聯(lián)網(wǎng)數(shù)據(jù)傳輸協(xié)議的概念虱朵,通過協(xié)議的約束莉炉,不同地域環(huán)境的計算機可以通過網(wǎng)絡(luò)完 成流暢的正確的數(shù)據(jù)交互。
計算機網(wǎng)絡(luò)數(shù)據(jù)傳輸協(xié)議目前最主流的就是歐洲計算機制造協(xié)會聯(lián)盟碴犬,也稱為國際標(biāo)準(zhǔn)化組 織 ISO 指定的 OSI/RM 七層網(wǎng)絡(luò)傳輸模型絮宁。
協(xié)議族
協(xié)議:通常指代單獨的一個協(xié)議,協(xié)議族通常指代互相關(guān)聯(lián)的一組協(xié)議服协,協(xié)議棧指代某一組互 相關(guān)聯(lián)的協(xié)議和他們所屬的 OSI 模型的層級結(jié)構(gòu)绍昂。
- 常見的網(wǎng)絡(luò)傳輸協(xié)議
協(xié)議名稱 | 協(xié)議描述 |
---|---|
HTTP | 超文本傳輸協(xié)議 |
HTTPS | 提供安全通道的超文本傳輸協(xié)議 |
FTP | 文件傳輸協(xié)議 |
SMTP | 簡單郵件傳輸協(xié)議 |
TELNET | 虛擬終端協(xié)議 |
SSH | 安全外殼協(xié)議 |
POP3 | 郵局協(xié)議 ( 版本 3) |
IP | 數(shù)據(jù)包 交換 協(xié)議 |
TCP | 端對端傳輸協(xié)議 |
UDP | 數(shù)據(jù)廣播協(xié)議 |
DNS | 域名解析 協(xié)議,可以通過 nslookup查看域名解析信息 |
DHCP | 動態(tài)主機配置協(xié)議 |
PYTHON 傳輸層網(wǎng)絡(luò)編程
socket由來
python2.x/python3.x 對于網(wǎng)絡(luò)編程的支持都是非常友好的,本身支持兩部分非常有用 的網(wǎng)絡(luò)編程方式窘游。
? 傳統(tǒng)網(wǎng)絡(luò)編程
? 非阻塞異步網(wǎng)絡(luò)編程
底層通過套接字 socket 對象的連接唠椭,完成多種協(xié)議的網(wǎng)絡(luò)程序服務(wù)端/客戶端的開發(fā)和數(shù)據(jù)通信。
socket 最初是為同一主機上的應(yīng)用程序創(chuàng)建忍饰,是的主機上運行的一個程序與另一個程序之 間可以完成數(shù)據(jù)通信操作贪嫂,程序也稱為進(jìn)程,就出現(xiàn)了不同進(jìn)程間進(jìn)行數(shù)據(jù)交互的操作艾蓝,因 為交互的模式不同撩荣,所以也一般將程序中的套接字區(qū)分為兩種
? 面向文件的套接字:通過文件進(jìn)行數(shù)據(jù)交互
? 面向網(wǎng)絡(luò)的套接字:通過網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)交互
python中的套接字
套接字模型對象,為了能明確的表示網(wǎng)絡(luò)中一臺數(shù)據(jù)交互的主機饶深,需要通過 IP 地址尋址確 定主機位置餐曹,通過 PORT 端口號確定主機交互接口
在網(wǎng)絡(luò)套接字交互過程中,出現(xiàn)了兩種類型的套接字模型
? 面向連接的套接字模型
? 面向無連接的套接字模型
面向連接的套接字模型敌厘,在進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)傳輸過程中台猴,首先要創(chuàng)建一個連接模型,通過指定 的連接模型進(jìn)行數(shù)據(jù)的交互俱两,類似我們生活中撥打電話一樣饱狂,首先保證通話連接的基礎(chǔ)上才 能完成通話內(nèi)容的交互,比較經(jīng)典的如 TCP 端對端傳輸協(xié)議就是面向連接的套接字對象
面向無連接的套接字模型宪彩,在進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)傳輸過程中休讳,不需要有效的網(wǎng)絡(luò)連接模型,在數(shù)據(jù)傳輸過程中只負(fù)責(zé)發(fā)送/接受尿孔,不保證數(shù)據(jù)的完整性和實效性俊柔;類似我們生活中的廣播電臺、電視信號等等活合,操作效率要比面向連接的套接字模型更加高效雏婶;比較經(jīng)典的 UDP 廣播 協(xié)議使用的就是面向無連接的套接字對象
python 中提供的網(wǎng)絡(luò)連接套接字,主要包含在 socket 模塊中 socket 模塊提供了 socket()函數(shù)可以完成如上描述的各種網(wǎng)絡(luò)套接字的構(gòu)建白指、通信等操作
? 基本語法結(jié)構(gòu) socket.socket(socket_family, socket_type, protocal=0) socket_family:socket 地址家族留晚,AF_UNIX/AF_LOCAL 或者 AF_INET socket_type:socket 連接類型 面向連接的(SOCK_STREAM),面向無連接的(SOCK_DGRAME) protocal:傳輸協(xié)議告嘲,一般不用設(shè)置错维,使用默認(rèn)值進(jìn)行自動匹配就好
? 創(chuàng)建 TCP 協(xié)議的套接字 socket 對象
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
? 創(chuàng)建 UDP 協(xié)議的套接字 socket 對象
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ocket 套接字常用操作
屬性 | 描述 |
---|---|
s.bind() | 綁定(主機名稱、端口)到一個套接字上 |
s.listen() | 設(shè)置并啟動 TCP 監(jiān)聽 |
s.accept() | 等待客戶端連接 |
s.connect() | 連接指定服務(wù)器 |
s.connect_ex() | 連接指定服務(wù)器橄唬,如果出現(xiàn)錯誤返回錯誤信息 |
s.recv() | 接受 TCP 消息 |
s.recv_into( | 接受 TCP 消息到緩沖區(qū) |
s.send() | 發(fā)送 TCP 消息 |
s.sendall() | 完整發(fā)送 TCP 消息 |
s.recvfrom() | 接受 UDP 消息 |
s.recvfrom_into() | 接受 UDP 消息到緩沖區(qū) |
s.sendto() | 發(fā)送 UDP 消息 |
s.shutdown() | 關(guān)閉連接對 |
s.close() | 關(guān)閉套接字對 |
TCP編程
TCP:Transmission Control Protocal 傳輸控制協(xié)議 是一種面向連接的赋焕,可靠的、基于字節(jié)流的傳輸層通信協(xié)議
數(shù)據(jù)傳輸?shù)目煽啃缘奶幚矸绞皆玻?jīng)典的 TCP 模型中通過如下兩種方式完成連接的可靠性
? 三次握手建立連接 ?
A- > B:發(fā)送一個尋址請求碼 seq=100宏邮;
B->A:返回一個應(yīng)答 ack=101 ?
A->B:發(fā)送一個確認(rèn)請求碼 seq=101,確認(rèn)連接;
B->A:返回一個應(yīng)答 ack=300 ?
A->B:發(fā)送一個連接請求碼 ack=300蜜氨;
B->A:返回應(yīng)答 ack=80 ?
A 和 B 之間開始進(jìn)行數(shù)據(jù)交互
? 四次揮手?jǐn)嚅_連接 ?
A->B:發(fā)送一個數(shù)據(jù)驗證請求碼 seq=100械筛,
B->A:返回一個應(yīng)答 ack=101 ?
A->B:發(fā)送一個傳輸結(jié)束標(biāo)記:seq=101;
B->A:返回一個應(yīng)答 ack=200 ?
A->B:發(fā)送一個確認(rèn)結(jié)束標(biāo)記:seq=200飒炎;
B->A:返回一個應(yīng)答 ack=300 ?
A->B:發(fā)送連接斷開標(biāo)記:seq=300埋哟;
B->A:返回斷開連接應(yīng)答:ack=400
正是有了三次握手和四次揮手對于連接可靠性的保障,才讓 TCP 協(xié)議端對端的數(shù)據(jù)交互變 得可行郎汪,但是同樣由于該協(xié)議的過于可靠赤赊,被有心人利用經(jīng)常實施 DDOS 拒絕服務(wù)攻擊!
python環(huán)境下的TCP服務(wù)端開發(fā)
"""
tcp服務(wù)端開發(fā)
version 1.1.0
author lkk
email lkk199404@163.com
"""
import socket
# 定義服務(wù)端主機信息
HOST = ''
PORT = 8888
ADDRESS = (HOST, PORT)
BUFFER = 1024
# 創(chuàng)建可以操作tcp協(xié)議的socket對象
test_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 將socket對象與服務(wù)端主機信息進(jìn)行綁定
test_tcp.bind(ADDRESS)
# 開始監(jiān)聽
print('開始啟動服務(wù)端')
test_tcp.listen(255)
# 等待客服端的連接
while True:
print('等待客戶端連接>>>>')
client_socket, client_addr = test_tcp.accept()
print('客戶端:{}連接成功'.format(client_addr))
client_socket.send("歡迎您的使用".encode('gbk'))
while True:
info = client_socket.recv(BUFFER)
msg1 = input('服務(wù)端:')
client_socket.send(msg1.encode('gbk'))
try:
print('客戶端:{}'.format(info.decode('gbk')))
except:
print('客戶端:{}'.format(info.decode('gbk')))
if msg1 == b'bye':
print("客戶端:{}退出成功".format(client_addr))
client_socket.close()
break
# 關(guān)閉【服務(wù)端一般情況下不要求關(guān)閉】
tcp_socket.close()
python環(huán)境下的TCP客戶端開發(fā)
"""
tcp客戶端開發(fā)
version 1.1.0
author lkk
email lkk199404@163.com
"""
import socket
HOST = '192.168.11.203'
PORT = 8888
ADDRESS = (HOST, PORT)
BUFFER = 1024
test_client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
test_client.connect(ADDRESS)
while True:
info = test_client.recv(BUFFER)
print("服務(wù)端:", info.decode("gbk"))
msg1 = input('客戶端:')
test_client.send(msg1.encode('gbk'))
# print('客戶端:{}'.format())
if msg1 == 'bye':
test_client.close()
break