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的主要類型
Socket主要有三種類型:流套接字、數(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ù)有可能在傳輸過程中丟失或出現(xiàn)數(shù)據(jù)重復(fù),且無(wú)法保證順序地接收到數(shù)據(jù)。
- 原始套接字(SOCK_RAW):與上面兩種套接字的區(qū)別在于原始套接字可以讀寫內(nè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ù)是套接字類型,有socket.SOCK_STREAM、socket.SOCK_DGRAM、socket.SOCK_RAW,分別代表套接字的三種類型。
三、Socket服務(wù)端和客戶端相關(guān)函數(shù)
服務(wù)端使用的函數(shù)
函數(shù) | 描述 |
---|---|
s.bind() | 綁定地址(host,port)到套接字, 在 AF_INET下,以元組(host,port)的形式表示地址 |
s.listen() | 開始 TCP 監(jiān)聽。參數(shù)backlog是指操作系統(tǒng)可以掛起的最大連接數(shù)量。該值至少為 1,一般設(shè)置為5 |
s.accept() | 被動(dòng)接受TCP客戶端連接,阻塞式等待連接的到來 |
客戶端使用的函數(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表示沒有超時(shí)期 |
s.gettimeout() | 返回當(dāng)前超時(shí)期的值,單位是秒,如果沒有設(shè)置超時(shí)期,則返回None |
s.setblocking() | 如果參數(shù)flag為0,則將套接字設(shè)為非阻塞模式,否則將套接字設(shè)為阻塞模式(默認(rèn)值)。非阻塞模式下,如果調(diào)用recv()沒有發(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ā)來的數(shù)據(jù) if not data: logger.info(address[0] + '斷開連接') break client_socket.send(data.upper()) """ 可以使用else與上面的if形成搭配 自己的任意想要實(shí)現(xiàn)的功能 """ except ConnectionResetError: logger.error(address[0] + '異常斷開連接') 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新建項(xiàng)目自動(dòng)添加介紹和utf-8編碼的方法
這篇文章主要介紹了Python新建項(xiàng)目自動(dòng)添加介紹和utf-8編碼的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12jupyter notebook tensorflow打印device信息實(shí)例
這篇文章主要介紹了jupyter notebook tensorflow打印device信息實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04Python Json模塊中dumps、loads、dump、load函數(shù)介紹
本篇文章主要介紹了Python Json模塊中dumps、loads、dump、load函數(shù)介紹,詳細(xì)的介紹了這幾種函數(shù)的用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05利用Python程序讀取Excel創(chuàng)建折線圖
這篇文章主要介紹了利用Python程序讀取Excel創(chuàng)建折線圖,文章通過圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09python實(shí)現(xiàn)合并兩個(gè)排序的鏈表
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)合并兩個(gè)排序的鏈表,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03使用AJAX和Django獲取數(shù)據(jù)的方法實(shí)例
這篇文章主要給大家介紹了關(guān)于使用AJAX和Django獲取數(shù)據(jù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10