python環(huán)境下的tcp網(wǎng)絡(luò)編程
網(wǎng)絡(luò)概念
網(wǎng)絡(luò)是由節(jié)點(diǎn)和連線(xiàn)構(gòu)成禽作,表示諸多對(duì)象及其相互聯(lián)系。在數(shù)學(xué)上揩页,網(wǎng)絡(luò)是一種圖旷偿,一般認(rèn)為專(zhuān)指加權(quán)圖。網(wǎng)絡(luò)除了數(shù)學(xué)定義外,還有具體的物理含義萍程,即網(wǎng)絡(luò)是從某種相同類(lèi)型的實(shí)際問(wèn)題中抽象出來(lái)的模型幢妄。在計(jì)算機(jī)領(lǐng)域中,網(wǎng)絡(luò)是信息傳輸茫负、接收蕉鸳、共享的虛擬平臺(tái),通過(guò)它把各個(gè)點(diǎn)忍法、面潮尝、體的信息聯(lián)系到一起,從而實(shí)現(xiàn)這些資源的共享饿序。
客戶(hù)端/服務(wù)端
1.在計(jì)算機(jī)中勉失,客戶(hù)端和服務(wù)端的架構(gòu)模式,區(qū)分為硬件模式和軟件模式
- 硬件客戶(hù)端
客戶(hù)端(Client)或稱(chēng)為用戶(hù)端原探,是指與服務(wù)器相對(duì)應(yīng)戴质,為客戶(hù)提供本地服務(wù)的程序。除了一些只在本地運(yùn)行的應(yīng)用程序之外踢匣,一般安裝在普通的客戶(hù)機(jī)上告匠,需要與服務(wù)端互相配合運(yùn)行。因特網(wǎng)發(fā)展以后离唬,較常用的用戶(hù)端包括了如萬(wàn)維網(wǎng)使用的網(wǎng)頁(yè)瀏覽器后专,收寄電子郵件時(shí)的電子郵件客戶(hù)端,以及即時(shí)通訊的客戶(hù)端軟件等输莺。對(duì)于這一類(lèi)應(yīng)用程序戚哎,需要網(wǎng)絡(luò)中有相應(yīng)的服務(wù)器和服務(wù)程序來(lái)提供相應(yīng)的服務(wù),如數(shù)據(jù)庫(kù)服務(wù)嫂用,電子郵件服務(wù)等等型凳,這樣在客戶(hù)機(jī)和服務(wù)器端,需要建立特定的通信連接嘱函,來(lái)保證應(yīng)用程序的正常運(yùn)行甘畅。 - 服務(wù)端
服務(wù)端是為客戶(hù)端服務(wù)的,服務(wù)的內(nèi)容諸如向客戶(hù)端提供資源往弓,保存客戶(hù)端數(shù)據(jù)疏唾。 - 軟件客戶(hù)端/服務(wù)端
軟件服務(wù)器和硬件服務(wù)器不同的是:軟件服務(wù)器是安裝在硬件上的一種特殊的軟件,可以通 過(guò)程序的執(zhí)行完成數(shù)據(jù)檢索函似、數(shù)據(jù)處理槐脏、數(shù)據(jù)存取等等各種特性,再通過(guò)網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)的共享通信撇寞,完成提供網(wǎng)絡(luò)數(shù)據(jù)服務(wù)的功能顿天!
IP&PORT
- IP: internet protocal 網(wǎng)絡(luò)互聯(lián)協(xié)議堂氯,中文縮寫(xiě):網(wǎng)協(xié);英文縮寫(xiě):IP
- PORT:端口 在通過(guò) IP 地址確定了網(wǎng)絡(luò)上的某個(gè)具體主機(jī)之后牌废,具體的數(shù)據(jù)通信主要是通過(guò)工作在計(jì)算 機(jī)中的軟件執(zhí)行的祖灰。
- 計(jì)算機(jī)中的端口號(hào)的范圍是 0~65535 之間
端口號(hào)根據(jù)其使用場(chǎng)景,一般區(qū)分為公用端口畔规、動(dòng)態(tài)端口、保留端口
公用端口:0~1023
動(dòng)態(tài)端口:1024~65535
保留端口:一般是 unix 系統(tǒng)中超級(jí)用戶(hù)進(jìn)程分配保留端口號(hào)
協(xié)議
協(xié)議:英文名稱(chēng) protocal恨统,是多方協(xié)商計(jì)議之后得出的約定叁扫、規(guī)則、規(guī)范 (ps:不是強(qiáng)制約定的)
通常情況下為了讓工作在網(wǎng)絡(luò)中的多臺(tái)計(jì)算機(jī)之間能友好的完成不同軟件的數(shù)據(jù)的通信畜埋,出現(xiàn)了互聯(lián)網(wǎng)數(shù)據(jù)傳輸協(xié)議的概念莫绣,通過(guò)協(xié)議的約束,不同地域環(huán)境的計(jì)算機(jī)可以通過(guò)網(wǎng)絡(luò)完 成流暢的正確的數(shù)據(jù)交互悠鞍。
計(jì)算機(jī)網(wǎng)絡(luò)數(shù)據(jù)傳輸協(xié)議目前最主流的就是歐洲計(jì)算機(jī)制造協(xié)會(huì)聯(lián)盟对室,也稱(chēng)為國(guó)際標(biāo)準(zhǔn)化組 織 ISO 指定的 OSI/RM 七層網(wǎng)絡(luò)傳輸模型。
協(xié)議族
協(xié)議:通常指代單獨(dú)的一個(gè)協(xié)議咖祭,協(xié)議族通常指代互相關(guān)聯(lián)的一組協(xié)議掩宜,協(xié)議棧指代某一組互 相關(guān)聯(lián)的協(xié)議和他們所屬的 OSI 模型的層級(jí)結(jié)構(gòu)。
- 常見(jiàn)的網(wǎng)絡(luò)傳輸協(xié)議
協(xié)議名稱(chēng) | 協(xié)議描述 |
---|---|
HTTP | 超文本傳輸協(xié)議 |
HTTPS | 提供安全通道的超文本傳輸協(xié)議 |
FTP | 文件傳輸協(xié)議 |
SMTP | 簡(jiǎn)單郵件傳輸協(xié)議 |
TELNET | 虛擬終端協(xié)議 |
SSH | 安全外殼協(xié)議 |
POP3 | 郵局協(xié)議 ( 版本 3) |
IP | 數(shù)據(jù)包 交換 協(xié)議 |
TCP | 端對(duì)端傳輸協(xié)議 |
UDP | 數(shù)據(jù)廣播協(xié)議 |
DNS | 域名解析 協(xié)議么翰,可以通過(guò) nslookup查看域名解析信息 |
DHCP | 動(dòng)態(tài)主機(jī)配置協(xié)議 |
PYTHON 傳輸層網(wǎng)絡(luò)編程
socket由來(lái)
python2.x/python3.x 對(duì)于網(wǎng)絡(luò)編程的支持都是非常友好的牺汤,本身支持兩部分非常有用 的網(wǎng)絡(luò)編程方式。
? 傳統(tǒng)網(wǎng)絡(luò)編程
? 非阻塞異步網(wǎng)絡(luò)編程
底層通過(guò)套接字 socket 對(duì)象的連接浩嫌,完成多種協(xié)議的網(wǎng)絡(luò)程序服務(wù)端/客戶(hù)端的開(kāi)發(fā)和數(shù)據(jù)通信檐迟。
socket 最初是為同一主機(jī)上的應(yīng)用程序創(chuàng)建,是的主機(jī)上運(yùn)行的一個(gè)程序與另一個(gè)程序之 間可以完成數(shù)據(jù)通信操作码耐,程序也稱(chēng)為進(jìn)程追迟,就出現(xiàn)了不同進(jìn)程間進(jìn)行數(shù)據(jù)交互的操作,因 為交互的模式不同骚腥,所以也一般將程序中的套接字區(qū)分為兩種
? 面向文件的套接字:通過(guò)文件進(jìn)行數(shù)據(jù)交互
? 面向網(wǎng)絡(luò)的套接字:通過(guò)網(wǎng)絡(luò)進(jìn)行數(shù)據(jù)交互
python中的套接字
套接字模型對(duì)象敦间,為了能明確的表示網(wǎng)絡(luò)中一臺(tái)數(shù)據(jù)交互的主機(jī),需要通過(guò) IP 地址尋址確 定主機(jī)位置束铭,通過(guò) PORT 端口號(hào)確定主機(jī)交互接口
在網(wǎng)絡(luò)套接字交互過(guò)程中每瞒,出現(xiàn)了兩種類(lèi)型的套接字模型
? 面向連接的套接字模型
? 面向無(wú)連接的套接字模型
面向連接的套接字模型,在進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)傳輸過(guò)程中纯露,首先要?jiǎng)?chuàng)建一個(gè)連接模型剿骨,通過(guò)指定 的連接模型進(jìn)行數(shù)據(jù)的交互,類(lèi)似我們生活中撥打電話(huà)一樣埠褪,首先保證通話(huà)連接的基礎(chǔ)上才 能完成通話(huà)內(nèi)容的交互浓利,比較經(jīng)典的如 TCP 端對(duì)端傳輸協(xié)議就是面向連接的套接字對(duì)象
面向無(wú)連接的套接字模型挤庇,在進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)傳輸過(guò)程中,不需要有效的網(wǎng)絡(luò)連接模型贷掖,在數(shù)據(jù)傳輸過(guò)程中只負(fù)責(zé)發(fā)送/接受嫡秕,不保證數(shù)據(jù)的完整性和實(shí)效性;類(lèi)似我們生活中的廣播電臺(tái)苹威、電視信號(hào)等等昆咽,操作效率要比面向連接的套接字模型更加高效菩佑;比較經(jīng)典的 UDP 廣播 協(xié)議使用的就是面向無(wú)連接的套接字對(duì)象
python 中提供的網(wǎng)絡(luò)連接套接字买雾,主要包含在 socket 模塊中 socket 模塊提供了 socket()函數(shù)可以完成如上描述的各種網(wǎng)絡(luò)套接字的構(gòu)建、通信等操作
? 基本語(yǔ)法結(jié)構(gòu) socket.socket(socket_family, socket_type, protocal=0) socket_family:socket 地址家族炫加,AF_UNIX/AF_LOCAL 或者 AF_INET socket_type:socket 連接類(lèi)型 面向連接的(SOCK_STREAM)窟哺,面向無(wú)連接的(SOCK_DGRAME) protocal:傳輸協(xié)議泻轰,一般不用設(shè)置,使用默認(rèn)值進(jìn)行自動(dòng)匹配就好
? 創(chuàng)建 TCP 協(xié)議的套接字 socket 對(duì)象
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
? 創(chuàng)建 UDP 協(xié)議的套接字 socket 對(duì)象
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ocket 套接字常用操作
屬性 | 描述 |
---|---|
s.bind() | 綁定(主機(jī)名稱(chēng)且轨、端口)到一個(gè)套接字上 |
s.listen() | 設(shè)置并啟動(dòng) TCP 監(jiān)聽(tīng) |
s.accept() | 等待客戶(hù)端連接 |
s.connect() | 連接指定服務(wù)器 |
s.connect_ex() | 連接指定服務(wù)器浮声,如果出現(xiàn)錯(cuò)誤返回錯(cuò)誤信息 |
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)閉連接對(duì) |
s.close() | 關(guān)閉套接字對(duì) |
TCP編程
TCP:Transmission Control Protocal 傳輸控制協(xié)議 是一種面向連接的,可靠的旋奢、基于字節(jié)流的傳輸層通信協(xié)議
數(shù)據(jù)傳輸?shù)目煽啃缘奶幚矸绞接净樱?jīng)典的 TCP 模型中通過(guò)如下兩種方式完成連接的可靠性
? 三次握手建立連接 ?
A- > B:發(fā)送一個(gè)尋址請(qǐng)求碼 seq=100;
B->A:返回一個(gè)應(yīng)答 ack=101 ?
A->B:發(fā)送一個(gè)確認(rèn)請(qǐng)求碼 seq=101至朗,確認(rèn)連接羡洁;
B->A:返回一個(gè)應(yīng)答 ack=300 ?
A->B:發(fā)送一個(gè)連接請(qǐng)求碼 ack=300;
B->A:返回應(yīng)答 ack=80 ?
A 和 B 之間開(kāi)始進(jìn)行數(shù)據(jù)交互
? 四次揮手?jǐn)嚅_(kāi)連接 ?
A->B:發(fā)送一個(gè)數(shù)據(jù)驗(yàn)證請(qǐng)求碼 seq=100爽丹,
B->A:返回一個(gè)應(yīng)答 ack=101 ?
A->B:發(fā)送一個(gè)傳輸結(jié)束標(biāo)記:seq=101筑煮;
B->A:返回一個(gè)應(yīng)答 ack=200 ?
A->B:發(fā)送一個(gè)確認(rèn)結(jié)束標(biāo)記:seq=200;
B->A:返回一個(gè)應(yīng)答 ack=300 ?
A->B:發(fā)送連接斷開(kāi)標(biāo)記:seq=300粤蝎;
B->A:返回?cái)嚅_(kāi)連接應(yīng)答:ack=400
正是有了三次握手和四次揮手對(duì)于連接可靠性的保障真仲,才讓 TCP 協(xié)議端對(duì)端的數(shù)據(jù)交互變 得可行,但是同樣由于該協(xié)議的過(guò)于可靠初澎,被有心人利用經(jīng)常實(shí)施 DDOS 拒絕服務(wù)攻擊秸应!
python環(huán)境下的TCP服務(wù)端開(kāi)發(fā)
"""
tcp服務(wù)端開(kāi)發(fā)
version 1.1.0
author lkk
email lkk199404@163.com
"""
import socket
# 定義服務(wù)端主機(jī)信息
HOST = ''
PORT = 8888
ADDRESS = (HOST, PORT)
BUFFER = 1024
# 創(chuàng)建可以操作tcp協(xié)議的socket對(duì)象
test_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 將socket對(duì)象與服務(wù)端主機(jī)信息進(jìn)行綁定
test_tcp.bind(ADDRESS)
# 開(kāi)始監(jiān)聽(tīng)
print('開(kāi)始啟動(dòng)服務(wù)端')
test_tcp.listen(255)
# 等待客服端的連接
while True:
print('等待客戶(hù)端連接>>>>')
client_socket, client_addr = test_tcp.accept()
print('客戶(hù)端:{}連接成功'.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('客戶(hù)端:{}'.format(info.decode('gbk')))
except:
print('客戶(hù)端:{}'.format(info.decode('gbk')))
if msg1 == b'bye':
print("客戶(hù)端:{}退出成功".format(client_addr))
client_socket.close()
break
# 關(guān)閉【服務(wù)端一般情況下不要求關(guān)閉】
tcp_socket.close()
python環(huán)境下的TCP客戶(hù)端開(kāi)發(fā)
"""
tcp客戶(hù)端開(kāi)發(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('客戶(hù)端:')
test_client.send(msg1.encode('gbk'))
# print('客戶(hù)端:{}'.format())
if msg1 == 'bye':
test_client.close()
break