python?Socket無(wú)限發(fā)送接收數(shù)據(jù)方式
一、關(guān)于Socket
Socket簡(jiǎn)介
Socket是指套接字,是對(duì)網(wǎng)絡(luò)中不同主機(jī)上的應(yīng)用進(jìn)程之間進(jìn)行雙向通信的端點(diǎn)的一種抽象。
一個(gè)套接字就是網(wǎng)絡(luò)上進(jìn)程通信的一端,提供了應(yīng)用層進(jìn)程利用網(wǎng)絡(luò)協(xié)議交換數(shù)據(jù)的機(jī)制。
Socket的主要類(lèi)型
Socket主要有三種類(lèi)型:流套接字、數(shù)據(jù)報(bào)套接字、原始套接字。
- 流套接字(SOCK_STREAM):采用了TCP協(xié)議,用于提供面向連接、可靠的數(shù)據(jù)傳輸服務(wù)。
- 數(shù)據(jù)報(bào)套接字(SOCK_DGRAM):采用了UDP協(xié)議,提供一種無(wú)連接的服務(wù)。該服務(wù)并不能保證數(shù)據(jù)傳輸?shù)目煽啃?,?shù)據(jù)有可能在傳輸過(guò)程中丟失或出現(xiàn)數(shù)據(jù)重復(fù),且無(wú)法保證順序地接收到數(shù)據(jù)。
- 原始套接字(SOCK_RAW):與上面兩種套接字的區(qū)別在于原始套接字可以讀寫(xiě)內(nèi)核沒(méi)有處理的IP數(shù)據(jù)包,而流套接字只能讀取TCP協(xié)議的數(shù)據(jù),數(shù)據(jù)報(bào)套接字只能讀取UDP協(xié)議的數(shù)據(jù)。
本文中講的是采用TCP協(xié)議,即流套接字。
二、Python的socket模塊
Python中進(jìn)行網(wǎng)絡(luò)編程的主要是使用socket模塊,當(dāng)然還有高級(jí)一點(diǎn)的網(wǎng)絡(luò)服務(wù)模塊SocketServer等內(nèi)容。本文中主要使用的是socket模塊。
socket模塊中首先需要使用socket()方法創(chuàng)建套接字對(duì)象,代碼示例如下:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
其中,
- 第一個(gè)參數(shù)是代表套接字家族,一般有socket.AF_UNIX、socket.AF_INET、socket.AF_INET6可以選擇。AF_UNIX是本機(jī)的通信,AF_INET和AF_INET6分別是IPv4和IPv6。
- 第二個(gè)參數(shù)是套接字類(lèi)型,有socket.SOCK_STREAM、socket.SOCK_DGRAM、socket.SOCK_RAW,分別代表套接字的三種類(lèi)型。
三、Socket服務(wù)端和客戶端相關(guān)函數(shù)
服務(wù)端使用的函數(shù)
| 函數(shù) | 描述 |
|---|---|
| s.bind() | 綁定地址(host,port)到套接字, 在 AF_INET下,以元組(host,port)的形式表示地址 |
| s.listen() | 開(kāi)始 TCP 監(jiān)聽(tīng)。參數(shù)backlog是指操作系統(tǒng)可以掛起的最大連接數(shù)量。該值至少為 1,一般設(shè)置為5 |
| s.accept() | 被動(dòng)接受TCP客戶端連接,阻塞式等待連接的到來(lái) |
客戶端使用的函數(shù)
| 函數(shù) | 描述 |
|---|---|
| s.connect() | TCP服務(wù)器連接,參數(shù)address的格式為元組(hostname,port),如果連接出錯(cuò),返回socket.error錯(cuò)誤。 |
| s.connect_ex() | connect()函數(shù)的擴(kuò)展版本,出錯(cuò)時(shí)返回出錯(cuò)碼,而不是拋出異常 |
服務(wù)端和客戶端都可以使用的函數(shù)
| 函數(shù) | 描述 |
|---|---|
| s.recv() | 接收 TCP 數(shù)據(jù),數(shù)據(jù)以字符串形式返回,bufsize 指定要接收的最大數(shù)據(jù)量 |
| s.send() | 發(fā)送 TCP 數(shù)據(jù),將參數(shù)string 中的數(shù)據(jù)發(fā)送到連接的套接字 |
| s.sendall() | 完整發(fā)送 TCP 數(shù)據(jù)。將參數(shù) string 中的數(shù)據(jù)發(fā)送到連接的套接字,但在返回之前會(huì)嘗試發(fā)送所有數(shù)據(jù)。成功返回 None,失敗則拋出異常。 |
| s.close() | 關(guān)閉套接字 |
| s.getpeername() | 返回連接套接字的遠(yuǎn)程地址。返回值通常是元組(ipaddr,port) |
| s.getsockname() | 返回套接字自己的地址。通常是一個(gè)元組(ipaddr,port) |
| s.setsockopt() | 設(shè)置給定套接字選項(xiàng)的值 |
| s.getsockopt() | 返回套接字選項(xiàng)的值 |
| s.settimeout() | 設(shè)置套接字操作的超時(shí)期,參數(shù)timeout是一個(gè)浮點(diǎn)數(shù),單位是秒。值為None表示沒(méi)有超時(shí)期 |
| s.gettimeout() | 返回當(dāng)前超時(shí)期的值,單位是秒,如果沒(méi)有設(shè)置超時(shí)期,則返回None |
| s.setblocking() | 如果參數(shù)flag為0,則將套接字設(shè)為非阻塞模式,否則將套接字設(shè)為阻塞模式(默認(rèn)值)。非阻塞模式下,如果調(diào)用recv()沒(méi)有發(fā)現(xiàn)任何數(shù)據(jù),或send()調(diào)用無(wú)法立即發(fā)送數(shù)據(jù),那么將引起socket.error異常 |
四、服務(wù)器端代碼
import socket
def socket_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = '' # ip可以是127.0.0.1,也可以為空
port = 0000 # 端口號(hào)
server_socket.bind((ip, port))
server_socket.listen(5)
logger.info('等待連接')
while True:
try:
client_socket, address = server_socket.accept()
logger.info(address[0] + '已連接')
while True:
data = client_socket.recv(1024) # 接受客戶端發(fā)來(lái)的數(shù)據(jù)
if not data:
logger.info(address[0] + '斷開(kāi)連接')
break
client_socket.send(data.upper())
"""
可以使用else與上面的if形成搭配
自己的任意想要實(shí)現(xiàn)的功能
"""
except ConnectionResetError:
logger.error(address[0] + '異常斷開(kāi)連接')
continue
except KeyboardInterrupt:
logger.info('服務(wù)器關(guān)閉')
break
server_socket.close()
if __name__ == '__main__':
socket_server()五、客戶端代碼
import socket
def socket_client():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = '' # ip可以為127.0.0.1,也可以為服務(wù)器的IP,例:10.0.0.xxx
port = 0000 # 必須與服務(wù)器端口號(hào)一致
client_socket.connect((ip, port))
while True:
msg = input('>>').strip()
if not msg:
continue
client_socket.send(msg.encode('utf-8')) # 客戶端發(fā)送數(shù)據(jù)
data = client_socket.recv(1024) # 接收服務(wù)端返回的數(shù)據(jù)
print(data.decode("utf-8"))
# break 無(wú)break可以循環(huán)發(fā)送
client_socket.close()
if __name__ == '__main__':
socket_client()注:
客戶端和服務(wù)端再接收發(fā)送數(shù)據(jù)時(shí),都需要注意數(shù)據(jù)格式,即decode()和encode()。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python實(shí)現(xiàn)RLE格式與PNG格式互轉(zhuǎn)
在機(jī)器視覺(jué)領(lǐng)域的深度學(xué)習(xí)中,很多數(shù)據(jù)集的標(biāo)注文件使用RLE的格式。但是神經(jīng)網(wǎng)絡(luò)的輸入一定是一張圖片,為此必須把RLE格式的文件轉(zhuǎn)變?yōu)閳D像格式。本文將利用Python實(shí)現(xiàn)RLE格式與PNG格式互轉(zhuǎn),感興趣的可以了解一下2022-08-08
Python list和str互轉(zhuǎn)的實(shí)現(xiàn)示例
這篇文章主要介紹了Python list和str互轉(zhuǎn)的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Django3.2 自動(dòng)發(fā)現(xiàn)所有路由代碼詳解
這篇文章主要為大家介紹了Django自動(dòng)發(fā)現(xiàn)所有路由的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2021-12-12
Kmeans均值聚類(lèi)算法原理以及Python如何實(shí)現(xiàn)
這個(gè)算法中文名為k均值聚類(lèi)算法,首先我們?cè)诙S的特殊條件下討論其實(shí)現(xiàn)的過(guò)程,方便大家理解。2020-09-09
python制作一個(gè)簡(jiǎn)單的gui 數(shù)據(jù)庫(kù)查詢界面
這篇文章主要介紹了python制作一個(gè)簡(jiǎn)單的gui 數(shù)據(jù)庫(kù)查詢界面,幫助大家更好的理解和學(xué)習(xí)python tkinter的使用,感興趣的朋友可以了解下2020-11-11
openCV實(shí)踐項(xiàng)目之銀行卡卡號(hào)識(shí)別功能
最近在惡補(bǔ)opencv,在前期不太那么認(rèn)真的學(xué)習(xí)狀態(tài)下,著手搞了一下這個(gè)小項(xiàng)目實(shí)戰(zhàn),基于模板匹配下的銀行卡卡號(hào)識(shí)別,下面這篇文章主要給大家介紹了關(guān)于openCV實(shí)踐項(xiàng)目之銀行卡卡號(hào)識(shí)別功能的相關(guān)資料,需要的朋友可以參考下2022-11-11
Python設(shè)計(jì)模式行為型責(zé)任鏈模式
這篇文章主要介紹了Python設(shè)計(jì)模式行為型責(zé)任鏈模式,責(zé)任鏈模式將能處理請(qǐng)求的對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求,直到有一個(gè)對(duì)象處理請(qǐng)求為止,避免請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系,下圍繞改內(nèi)容介紹具有一點(diǎn)的參考價(jià)值,需要的朋友可以參考下2022-02-02
Broadcast廣播機(jī)制在Pytorch Tensor Numpy中的使用詳解
python中Broadcast機(jī)制非常實(shí)用,在python中的廣播機(jī)制其實(shí)很簡(jiǎn)單,下方主要介紹Broadcast廣播機(jī)制在Pytorch Tensor Numpy中的使用,希望對(duì)你有所幫助2022-08-08
pygame庫(kù)實(shí)現(xiàn)移動(dòng)底座彈球小游戲
這篇文章主要為大家詳細(xì)介紹了pygame庫(kù)實(shí)現(xiàn)移動(dòng)底座彈球小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11

