python_socket
1.什么是socket編程
網(wǎng)絡(luò)世界基本都是TCP/IP協(xié)議進(jìn)行通訊
TCP/IP協(xié)議是一種傳輸數(shù)據(jù)的方案
若使用requests庫(kù),發(fā)送HTTP請(qǐng)求消息,其實(shí)requests庫(kù)底層也是使用的socket編程接口
2.python語(yǔ)言中的socket編程
要進(jìn)行socket編程,發(fā)送網(wǎng)絡(luò)信息,我們可以使用python內(nèi)置的socket庫(kù),目前的socket編程,使用最多的就是通過(guò)TCP協(xié)議進(jìn)行網(wǎng)絡(luò)通訊,TCP通訊的雙方分別為服務(wù)端和客戶(hù)端,雙方需要建立一個(gè)虛擬的連接,然后雙方程序,才能發(fā)送業(yè)務(wù)數(shù)據(jù)信息,建立TCP虛擬連接是通過(guò)三次握手進(jìn)行的。
1)服務(wù)端程序
# ============TCP 服務(wù)端程序(Linux)==================
# 導(dǎo)入socket庫(kù)
from socket import *# 主機(jī)地址為0.0.0.0,表示綁定本機(jī)所有網(wǎng)絡(luò)接口IP地址
# 等待客戶(hù)端來(lái)連接
IP = '10.20.152.215'
# 端口號(hào)
PORT = 50000
#定義一次從socket緩沖區(qū)最多讀入512個(gè)字節(jié)數(shù)據(jù)
BUFLEN = 512# 實(shí)例化一個(gè)socket對(duì)象,給一個(gè)類(lèi)加上括號(hào),進(jìn)行實(shí)例化
# 參數(shù)AF_INET表示socket網(wǎng)絡(luò)層使用IP協(xié)議
# 參數(shù)SOCK_STREAM表示socket傳輸層使用TCP協(xié)議
listenSocket = socket(AF_INET, SOCK_STREAM) # 等待客戶(hù)端連接# socket綁定IP地址和端口號(hào)
listenSocket.bind((IP, PORT))# 使用socket處于監(jiān)聽(tīng)狀態(tài),等待客戶(hù)端的連接請(qǐng)求
# 參數(shù)5表示,最多接受多少個(gè)等待連接的客戶(hù)端
listenSocket.listen(5)
print(f'服務(wù)端啟動(dòng)成功,在{PORT}端口等待客戶(hù)端連接...')dataSocket , addr = listenSocket.accept()
print('接受一個(gè)客戶(hù)端連接:',addr)while True:# 嘗試讀取對(duì)方發(fā)送的消息# BUFLEN 指定從接收緩沖里最多讀取多少個(gè)字節(jié)recved = dataSocket.recv(BUFLEN)# 如果返回空bytes,表示對(duì)方關(guān)閉了連接# 退出循環(huán),結(jié)束消息收發(fā)if not recved:break# 讀取的字節(jié)數(shù)據(jù)是bytes類(lèi)型,需要解碼為字符串info = recved.decode()print(f'收到對(duì)方信息:{info}')# 發(fā)送的數(shù)據(jù)類(lèi)型必須是bytes,所以要編碼dataSocket.send(f'服務(wù)端接收到了信息{info}'.encode())# 服務(wù)端也調(diào)用close()關(guān)閉socket
dataSocket.close()
listenSocket.close()
2)客戶(hù)端程序
# ============TCP 客戶(hù)端程序(TE)==================
# 導(dǎo)入socket庫(kù)
from socket import *IP = '10.20.152.215'
SERVER_PORT = 50000
BUFLEN = 512# 實(shí)例化一個(gè)socket對(duì)象,指明協(xié)議,給一個(gè)類(lèi)加上括號(hào),進(jìn)行實(shí)例化
dataSocket = socket(AF_INET,SOCK_STREAM)# 連接服務(wù)端socket
dataSocket.connect((IP,SERVER_PORT))while True:# 從終端讀入用戶(hù)輸入的字符串toSend = input('>>>')if toSend == 'exit':break# 發(fā)送消息,也要編碼為bytesdataSocket.send(toSend.encode())# 等待接受服務(wù)端的消息recved = dataSocket.recv(BUFLEN)# 如果返回空bytes,表示對(duì)方關(guān)閉了連接if not recved:break# 打印讀取的消息print(recved.decode())dataSocket.close()
3.應(yīng)用消息格式
實(shí)際企業(yè)開(kāi)發(fā)過(guò)程中,消息往往是有格式定義的,消息的格式定義往往可以歸入OSI網(wǎng)絡(luò)模型的表示層。
比如:定義消息頭、消息體
消息頭存放消息的格式數(shù)據(jù),比如長(zhǎng)度、類(lèi)型、狀態(tài)等,消息體存放具體的傳送數(shù)據(jù)
TCP協(xié)議傳輸?shù)氖?strong>字節(jié)流(bytes stream),如果消息中沒(méi)有明確的消息邊界,接收方不一定知道一個(gè)完整的消息從字節(jié)流的哪里開(kāi)始到哪里結(jié)束。
指定消息的邊界有兩種形式
1)用特殊字節(jié)作為消息的結(jié)尾符號(hào):可以用消息內(nèi)容中不可能出現(xiàn)的字節(jié)串(如FFFFFF)作為消息的結(jié)尾字符。
2)在消息開(kāi)頭的某個(gè)位置,直接指定消息的長(zhǎng)度:UDP協(xié)議通常不需要指定消息的邊界,因?yàn)閁DP是數(shù)據(jù)報(bào)協(xié)議,應(yīng)用程序從socket接收到的必定是發(fā)送放發(fā)送的完整信息。
總結(jié)
以上是生活随笔為你收集整理的python_socket的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 为何美国电影变形金刚5,被定义为烂片
- 下一篇: PaddleClas