通過(guò)python的網(wǎng)絡(luò)通信支持,通過(guò)網(wǎng)絡(luò)模塊博肋,python程序可以非常方便地相互訪問(wèn)互聯(lián)網(wǎng)上的HTTP服務(wù)和FTP服務(wù)等痒芝。可以直接獲取互聯(lián)網(wǎng)上的遠(yuǎn)程資源静秆,還可以向遠(yuǎn)程資源發(fā)送GET POST請(qǐng)求粮揉。
(一)了解計(jì)算機(jī)網(wǎng)絡(luò)的基礎(chǔ)知識(shí)
計(jì)算機(jī)網(wǎng)絡(luò)是線代通信技術(shù)與計(jì)算機(jī)技術(shù)相結(jié)合的產(chǎn)物,計(jì)算機(jī)網(wǎng)絡(luò)主要可以提供
- 資源共享
- 信息傳輸與集中處理
- 均衡負(fù)荷與分布處理
- 綜合信息服務(wù)
按照規(guī)模大小和延伸范圍可以分為:廣域網(wǎng)(WAN)抚笔,城域網(wǎng)(MAN)扶认,局域網(wǎng)(LAN)
計(jì)算機(jī)網(wǎng)絡(luò)中實(shí)現(xiàn)通信必須有一些約定,這些約定被稱(chēng)為通信協(xié)議殊橙。通信協(xié)議負(fù)責(zé)傳輸速率辐宾,傳輸代碼,代碼結(jié)構(gòu)膨蛮,傳輸控制步驟叠纹、出錯(cuò)控制等標(biāo)準(zhǔn)。
通信協(xié)議一般由三部分組成:一是語(yǔ)義部分敞葛,用于決定雙方對(duì)話類(lèi)型誉察;二是語(yǔ)法部分,用于決定雙方對(duì)話的格式惹谐;三是變化規(guī)則持偏,用于決定通信雙方的應(yīng)答關(guān)系。
OSI 參考模型把計(jì)算機(jī)劃分為:物理層氨肌,數(shù)據(jù)鏈路層鸿秆,網(wǎng)絡(luò)層,傳輸層怎囚,會(huì)話層卿叽,表示層,應(yīng)用層七層桩了。
應(yīng)用層:與其它計(jì)算機(jī)進(jìn)行通訊的一個(gè)應(yīng)用附帽,它是對(duì)應(yīng)應(yīng)用程序的通信服務(wù)的。有HTTP, FTP , NFS, SMTP, TELNET
表示層:這一層主要是定義數(shù)據(jù)格式及加密井誉。如加密蕉扮, ASCII
會(huì)話層:它定義了如何開(kāi)始、控制和結(jié)束一個(gè)會(huì)話颗圣,包括對(duì)多個(gè)雙向消息的控制和管理喳钟,以便在只完成連續(xù)消息的一部分時(shí)可以通知應(yīng)用屁使,從而使表示層看到的數(shù)據(jù)是連續(xù)的。如 RPC,SQL
傳輸層:這層的功能包括是否選擇差錯(cuò)恢復(fù)協(xié)議還是無(wú)差錯(cuò)恢復(fù)協(xié)議奔则,及在泳衣主機(jī)上對(duì)不同應(yīng)用的數(shù)據(jù)流的輸入進(jìn)行復(fù)用蛮寂,還包括對(duì)收到的順序不對(duì)的數(shù)據(jù)包的重新排序功能,如 TCP UDP SPX
網(wǎng)絡(luò)層:這層對(duì)端對(duì)端的包傳輸進(jìn)行定義易茬,它定義了能夠標(biāo)識(shí)所有結(jié)點(diǎn)的邏輯地址酬蹋,還定義了路由實(shí)現(xiàn)的方式和學(xué)習(xí)的方式。如IP
數(shù)據(jù)鏈路層:它定義了在單個(gè)鏈路上如何傳輸數(shù)據(jù)抽莱。這些協(xié)議與被討論的各種介質(zhì)有關(guān)
物理層:OSI的物理層規(guī)范是有關(guān)傳輸介質(zhì)的特性范抓,這些規(guī)范通常也參考了其他組織制定的標(biāo)準(zhǔn)。
IP地址用于唯一標(biāo)識(shí)網(wǎng)絡(luò)中的一個(gè)通信實(shí)體食铐,這個(gè)通信實(shí)體既可以是一個(gè)主機(jī)匕垫,也可以是路由器的某個(gè)端口,虐呻。而在基于IP協(xié)議的網(wǎng)絡(luò)中傳輸數(shù)據(jù)包都必須使用IP地址來(lái)進(jìn)行標(biāo)識(shí)象泵。
端口,程序與外界進(jìn)行交互的出入口斟叼。
公認(rèn)端口: 0 ~ 1023綁定了一些特定的服務(wù)
注冊(cè)端口 : 1024 ~ 49151 綁定一些業(yè)務(wù)
私有端口 : 49152 ~ 65535 應(yīng)用程序動(dòng)態(tài)的端口使用
(二)基于TCP協(xié)議的網(wǎng)絡(luò)編程
Tcp/IP通信協(xié)議是一種可靠的網(wǎng)絡(luò)協(xié)議偶惠,他在通信的兩端建立一個(gè)socket,從而形成虛擬的網(wǎng)絡(luò)鏈路犁柜。一旦建立了虛擬網(wǎng)絡(luò)鏈路洲鸠,兩端的程序就可以通過(guò)該鏈路進(jìn)行通信。
TCP 協(xié)議基礎(chǔ)
IP 是Internet上使用的一個(gè)關(guān)鍵協(xié)議馋缅,通過(guò)IP協(xié)議扒腕,使internet成為一個(gè)允許連接不同類(lèi)型的計(jì)算機(jī)和不同操作系統(tǒng)的網(wǎng)絡(luò)。同時(shí)還需要TCP協(xié)議來(lái)提供可靠且無(wú)差錯(cuò)的服務(wù)萤悴。
TCP協(xié)議被稱(chēng)為端對(duì)端協(xié)議瘾腰,這是因?yàn)樗趦膳_(tái)計(jì)算機(jī)的連接中起了非常重要的角色,當(dāng)一臺(tái)計(jì)算機(jī)需要與另外一臺(tái)計(jì)算機(jī)連接時(shí)覆履,TCP協(xié)議會(huì)讓他們之間建立一個(gè)虛擬鏈路蹋盆,用于發(fā)送和接受數(shù)據(jù)。
TCP協(xié)議負(fù)責(zé)收集這些數(shù)據(jù)包硝全,并將其按照適當(dāng)?shù)捻樞騻魉推芪恚邮斩耸盏綌?shù)據(jù)包后將其正確的還原。TCP保證數(shù)據(jù)包在傳送過(guò)程中準(zhǔn)確無(wú)誤伟众。TCP協(xié)議采用重發(fā)機(jī)制析藕,當(dāng)一個(gè)通信實(shí)體發(fā)送一個(gè)消息給另外一個(gè)通信實(shí)體后,需要接收到另外一個(gè)通信實(shí)體的確認(rèn)信息凳厢,如果沒(méi)有接收到該確認(rèn)信息账胧,則會(huì)重發(fā)信息竞慢。
使用socket創(chuàng)建TCP服務(wù)端
使用socket之前,必須先創(chuàng)建socket對(duì)象治泥,可通過(guò)該類(lèi)的構(gòu)造器來(lái)創(chuàng)建socket實(shí)例筹煮。
socket.socket(family = AF_INET, type= SOCK_STREAM, proto=0, fileno= None)
family 參數(shù)用于指定網(wǎng)絡(luò)的類(lèi)型。
type 參數(shù)用于指定網(wǎng)絡(luò)Sock類(lèi)型居夹。SOCK_STREAM(默認(rèn)值败潦,創(chuàng)建TCP協(xié)議的socket)
proto 參數(shù)用于指定協(xié)議號(hào),如果沒(méi)有特殊要求吮播,一般為0
在創(chuàng)建socket后要將兩個(gè)socket連接起來(lái)变屁。作為服務(wù)端使用的socket必須綁定IP地址和端口眼俊,并在端口進(jìn)行監(jiān)聽(tīng)意狠。
socket對(duì)象常用的方法:
socket.bind(address):將socket綁定到指定的address,指定的address可以是一個(gè)元組疮胖,包含IP 和端口
socket.accept() 作為服務(wù)端使用的socket調(diào)該方法接受來(lái)自客戶端的連接环戈。
socket.close()關(guān)閉連接
socket.recv(): 接收socket中的數(shù)據(jù),該方法返回一個(gè)bytes對(duì)象代表接收到的數(shù)據(jù)
socket.send(bytes[, flags]) 向socket中發(fā)送數(shù)據(jù)澎灸,該socket必須與遠(yuǎn)程socket之間建立了連接院塞。
socket.listen()服務(wù)端使用socket調(diào)用監(jiān)聽(tīng)
基本步驟
服務(wù)端先創(chuàng)建一個(gè)socket對(duì)象
服務(wù)端socket將自己綁定到指定IP和端口
服務(wù)端socket調(diào)用自己的listen()方法
-
程序不斷循環(huán)接收來(lái)自客戶端的連接
#創(chuàng)建socket對(duì)象 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 將socket綁定到本機(jī)IP地址和端口 s.bind(('0.0.0.0', 8000)) #服務(wù)端開(kāi)始監(jiān)聽(tīng)來(lái)自客戶端的連接 s.listen() while True: #每當(dāng)接收到客戶端請(qǐng)求時(shí),就返回對(duì)應(yīng)的socket和遠(yuǎn)程地址 c, addr = s.accept()
socket客戶端
創(chuàng)建客戶端的步驟:
客戶端先創(chuàng)建一個(gè)socket對(duì)象
-
客戶端socket調(diào)用connect() 方法連接遠(yuǎn)程服務(wù)器地址
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((('127.0.0.1', 8000)))
小實(shí)例:服務(wù)端
import socket
import threading
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('0.0.0.0', 8000))
server.listen()
def handle_sock(sock, addr):
while True:
data = sock.recv(1024)
print(data.decode("utf8"))
re_data = input()
sock.send(re_data.encode("utf8"))
while True:
sock, addr = server.accept()
'''用線程去處理新接收的連接(用戶)'''
client_thread = threading.Thread(target=handle_sock, args=(sock, addr))#傳的一定是函數(shù)名稱(chēng)
client_thread.start()
客戶端:
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 8000))
while True:
re_data = input()
client.send(re_data.encode("utf8"))
data = client.recv(1024)
print(data.decode("utf8"))
通過(guò)這樣就可以實(shí)現(xiàn)socket之間的通信性昭。