當前位置:首頁 » 編程語言 » pythonrecv阻塞

pythonrecv阻塞

發布時間: 2023-05-11 02:28:45

python socket 阻塞模式怎麼確保數據recv

可以通過setsockopt,或者更簡單的setblocking, settimeout設置。阻塞式的socket的recv服從這樣的規則:
當緩沖區內有數據時,立即返回所有的數據;當緩沖區內無數據時,阻塞直到緩沖區中有數據。非阻塞式的socket的recv服從的規則則是:
當緩沖區內有數據時,立即返回所有的數據;當緩沖區內無數據時,產生EAGAIN的錯誤並返回(在Python中會拋出一個異常)。兩種情況都不會返回空字元串,返回空數據的結果是對方關閉了連接之後才會出現的。

❷ 如何解決winsock中recv函數的阻塞問題,最好有代碼

Private Sub wskPb_DataArrival(ByVal bytesTotal As Long)
On Error Resume Next
Dim cData As String

wskPb.GetData cData
End Sub

一般VB的Socket數據接收在這里做操作,DataArrival事件前畝,相當於稿返一個回調函數,有收到數據就會觸發這個事件.
當然你也可鍵悔飢以開辟線程來避免阻塞問題.微軟都已經封裝好了,沒必要再自己做.

❸ 如何用Python實現實時的網路連接檢測

如果你用的socket包里的那些阻塞介面,當然寫個線程循環監測時間也沒啥,只不過記得在循環內加上個sleep,哪怕是1ms甚至1us的sleep都可以避免CPU被消耗干凈。

如果你所說的接收是死循環式里跑socket.recv,它會在recv里阻塞,按你的說法3分鍾一個心跳包,時間檢測就成了3分鍾一次,不太合適。

更好的辦法自然是通過epoll/poll之類的方式或者asyncio/twisted/tornado之類的非同步回調/協程加時間事件甚至是各種GUI框架的事件循環來啟動你的發送和接收。考慮到以後可能有多設備,顯然利用這些成型的玩意更合理。

❹ Python的多進程模塊multiprocessing

眾所周知,Python中不存在真正的多線程,Python中的多線程是一個並發過程。如果想要並行的執行程序,充分的利用cpu資源(cpu核心),還是需要使用多進程解決的。其中multiprocessing模塊應該是Python中最常用的多進程模塊了。

基本上multiprocessing這個模塊和threading這個模塊用法是相同的,也是可以通過函數和類創建進程。

上述案例基本上就是筆者搬用了上篇文章多線程的案例,可見其使用的相似之處。導入multiprocessing後實例化Process就可以創建一個進程,參數的話也是和多線程一樣,target放置進程執行函數,args存放該函數的參數。

使用類來創建進程也是需要先繼承multiprocessing.Process並且實現其init方法。

Pool可以提供指定數量的進程,供用戶調用,當有新的請求提交到pool中時,如果池還沒有滿,那麼就會創建一個新的進程用來執行該請求。

但如果池中的進程數已經達到規定最大值,那麼該請求就會等待,直到池中有進程結束,才會創建新的進程。

需要注意的是,在調用join方法阻塞進程前,需要先調用close方法,,否則程序會出錯。

在上述案例中,提到了非阻塞,當把創建進程的方法換為pool.apply(func, (msg,))時,就會阻塞進程,出現下面的狀況。

在multiprocessing模塊中還存在Queue對象,這是一個進程的安全隊列,近似queue.Queue。隊列一般也是需要配合多線程或者多進程使用。

下列案例是一個使用進程隊列實現的生產者消費者模式。

multiprocessing支持兩種進程間的通信,其中一種便是上述案例的隊列,另一種則稱作管道。在官方文檔的描述中,multiprocessing中的隊列是基於管道實現的,並且擁有更高的讀寫效率。

管道可以理解為進程間的通道,使用Pipe([plex])創建,並返回一個元組(conn1,conn2)。如果plex被置為True(默認值),那麼該管道是雙向的,如果plex被置為False,那麼該管道是單向的,即conn1隻能用於接收消息,而conn2僅能用於發送消息。

其中conn1、conn2表示管道兩端的連接對象,每個連接對象都有send()和recv()方法。send和recv方法分別是發送和接受消息的方法。例如,可以調用conn1.send發送消息,conn1.recv接收消息。如果沒有消息可接收,recv方法會一直阻塞。如果管道已經被關閉,那麼recv方法會拋出EOFError。

關於multiprocessing模塊其實還有很多實用的類和方法,由於篇幅有限(懶),筆者就先寫到這里。該模塊其實用起來很像threading模塊,像鎖對象和守護線程(進程)等multiprocessing模塊也是有的,使用方法也近乎相同。

如果想要更加詳細的了解multiprocessing模塊,請參考官方文檔。

❺ Python網路編程 -- TCP/IP

首先放出一個 TCP/IP 的程序,這里是單線程伺服器與客戶端,在多線程一節會放上多線程的TCP/IP服務程序沖戚拍。

這里將服務端和客戶端放到同一個程序當中,方便對比服務端與客戶端的不同。

TCP/IP是網際網路的通信協議,其參考OSI模型,也採用了分層的方式,對每一層制定了相應的標准。

網際協議(IP)是為全世界通過互聯網連接的計算機賦予統一地址系統的機制,它使得數據包能夠從互聯網的一端發送至另一端,如 130.207.244.244,為了便於記憶,常用主機名代替IP地址,例如 .com。

UDP (User Datagram Protocol,用戶數據報協議) 解決了上述第一個問題,通過埠號來實現了多路復用(用不同的埠區分不同的應用程序)但是使用UDP協議的網路程序需要自己處理丟包、重包和包的亂序問題。

TCP (Transmission Control Protocol,傳輸控制協議) 解決了上述兩個問題,同樣使用埠號實現了復用。

TCP 實現可靠連接的方法:

socket通信模型及 TCP 通信過程如下兩張圖。

[圖片上傳失敗...(image-6d947d-1610703914730)]

[圖片上傳失敗...(image-30b472-1610703914730)]

socket.getaddrinfo(host, port, family, socktype, proto, flags)
返回: [(family, socktype, proto, cannonname, sockaddr), ] 由元組組成的列表散羨。
family:表示socket使用的協議簇, AF_UNIX : 1, AF_INET: 2, AF_INET6 : 10。 0 表示不指定。
socktype: socket 的類型, SOCK_STREAM : 1, SOCK_DGRAM : 2, SOCK_RAW : 3
proto: 協議, 套接字所用的協議,如果不指定, 則為 0。 IPPROTO_TCP : 6, IPPRTOTO_UDP : 17
flags:標記,限制返回內容。 AI_ADDRCONFIG 把計算機無法連接的所有地址都過濾掉(如果一個機構既有IPv4,又有IPv6,而主機只有IPv4,則會把 IPv6過濾掉)
AI _V4MAPPED, 如果本機只有IPv6,服務卻只有IPv4,這個標記會將 IPv4地址重新編碼為可實際使用的IPv6地址。
AI_CANONNAME,返回規范主機名:cannonname。
getaddrinfo(None, 'smtp', 0, socket.SOCK_STREAM, 0, socket.AP_PASSIVE)
getaddrinfo('ftp.kernel.org', 'ftp', 0, 'socket.SOCK_STREAM, 0, socket.AI_ADDRCONFIG | socket.AI_V4MAPPED)
利用已經通信的套接字名提供給getaddrinfo
mysock = server_sock.accept()
addr, port = mysock.getpeername()
getaddrinfo(addr, port, mysock.family, mysock.type, mysock.proto, socket.AI_CANONNAME)

TCP 數據發送模式:

由於 TCP 是發送流式數據,並且會自動分割發送的數據包,而仔槐且在 recv 的時候會阻塞進程,直到接收到數據為止,因此會出現死鎖現象,及通信雙方都在等待接收數據導致無法響應,或者都在發送數據導致緩存區溢出。所以就有了封幀(framing)的問題,即如何分割消息,使得接收方能夠識別消息的開始與結束。

關於封幀,需要考慮的問題是, 接收方何時最終停止調用recv才是安全的?整個消息或數據何時才能完整無缺的傳達?何時才能將接收到的消息作為一個整體來解析或處理。

適用UDP的場景:

由於TCP每次連接與斷開都需要有三次握手,若有大量連接,則會產生大量的開銷,在客戶端與伺服器之間不存在長時間連接的情況下,適用UDP更為合適,尤其是客戶端太多的時候。

第二種情況: 當丟包現象發生時,如果應用程序有比簡單地重傳數據聰明得多的方法的話,那麼就不適用TCP了。例如,如果正在進行音頻通話,如果有1s的數據由於丟包而丟失了,那麼只是簡單地不斷重新發送這1s的數據直至其成功傳達是無濟於事的。反之,客戶端應該從傳達的數據包中任意選擇一些組合成一段音頻(為了解決這一問題,一個智能的音頻協議會用前一段音頻的高度壓縮版本作為數據包的開始部分,同樣將其後繼音頻壓縮,作為數據包的結束部分),然後繼續進行後續操作,就好像沒有發生丟包一樣。如果使用TCP,那麼這是不可能的,因為TCP會固執地重傳丟失的信息,即使這些信息早已過時無用也不例外。UDP數據報通常是互聯網實時多媒體流的基礎。

參考資料:

❻ recv是阻塞還是非阻塞的

網路編程函數如recv是阻塞(同步)還是非阻塞(非同步)取決於在調用recv函數前創建的套接字socket是阻塞還是非阻塞。socket默認創建時設定為阻塞模式;若要將socket設定為非阻塞模式,可以在socket創建時設定為非阻塞模式,那麼函數recv就是非阻塞的。
可以通過一下幾種方法設定socket為非阻塞:
1.linux平台可以在利用socket()函數創建socket時指定socket是非同步(非阻塞)的:
int socket(int domain, int type, int protocol);
在參數type中設置SOCK_NONBLOCK標志即可,例如:
int s = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
2.windows和linux平台accept()函數返回的socekt也是阻塞的,linux另外提供了一個accept4()函數,可以直接將socket設置為非阻塞模式:
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
只要將accept4()最後一個參數flags設置成SOCK_NONBLOCK即可。

3.除了在創建socket時,將socket設置為非阻塞模式,還可以通過以下函數來設置:

linux平台可以調用fcntl()或ioctl()函數,例如:
fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK);
ioctl(sockfd, FIONBIO, 1); //1:非阻塞 0:阻塞
windows平台可調用ioctlsocket函數:

int ioctlsocket(
_In_ SOCKET s,
_In_ long cmd,
_Inout_ u_long *argp
);
將cmd參數設置為FIONBIO,*argp=0即設置成阻塞模式,而*argp非0即可設置成非阻塞模式。但windows平台一個地方需要注意,如果對一個socket調用了WSAAsyncSelect()或WSAEventSelect()函數後,你再調用ioctlsocket()函數將該socket設置為阻塞模式,則會失敗,必須先調用WSAAsyncSelect()設置lEvent參數為0或調用WSAEventSelect()設置lNetworkEvents參數為0來分別禁用WSAAsyncSelect()或WSAEventSelect(),再次調用ioctlsocket()將該socket設置成阻塞模式才會成功。因為調用WSAAsyncSelect()或WSAEventSelect()函數會自動將socket設置成非阻塞模式。

❼ 為什麼我的socket recv()一直等待,接收不到東西

recv本身就是阻塞函數,必須在收到乎消消息之後才能歲返知返回,你沒收到消息,說明對方沒有給你發過來,或者網路故障等等都可能。

不知道你怎麼判斷伺服器有返回數據的,我覺得你需要判斷伺服器發世嘩送是否成功

❽ 多線程下recv為什麼不阻塞

1、有沒有把SOCKET設置成了非阻塞余清
2、_recv怎麼實現的,你給一個自己寫的豎歲前接收函數,雀或誰知道你在裡面搞了什麼鬼

❾ python serversocket 是非阻塞的嗎

Python 利用SocketServer模塊
實現網路客戶端與伺服器並發連接非阻塞通信
MyTCPServer.py
import SocketServer
from SocketServer import StreamRequestHandlerfrom time import ctime
host = '127.0.0.1'
port = 8001
addr = (host,port)
BUF_SIZE = 1024
class Servers(StreamRequestHandler):
def handle(self):
print 'connection from %s'%str(self.client_address)#self.wfile.write('connection %s:%s at %s succeed!' % (host,port,ctime()))while True:
try:
data = self.request.recv(1024)
if not data:
break
print "----\n%s\n[Recv]%s"%(str(self.client_address), data)self.request.send(data)
except:
break
print "disconnect %s"%str(self.client_address)print 'server is running....'
server = SocketServer.ThreadingTCPServer(addr,Servers)server.serve_forever()
MyTCPClient.py
from socket import *
host = '127.0.0.1'
port = 8001
addr = (host,port)
BUF_SIZE = 1024
client = socket(AF_INET,SOCK_STREAM)
client.connect(addr)
while True:
data = raw_input()
if data.strip() == 'exit':
break
if not data:
continue
client.send('%s\r\n'%data)
print "send:%s"%data
dataRecv = client.recv(BUF_SIZE)
print "recv:%s"%dataRecv
client.close()

熱點內容
ftp命令使用 發布:2025-07-18 18:13:05 瀏覽:44
辦稅密碼是什麼 發布:2025-07-18 18:12:32 瀏覽:486
linuxftp文件下載 發布:2025-07-18 18:12:30 瀏覽:940
互聯網網站伺服器搭建 發布:2025-07-18 18:01:06 瀏覽:478
安卓手機怎麼辮真偽 發布:2025-07-18 17:13:14 瀏覽:186
java後台json 發布:2025-07-18 17:12:21 瀏覽:680
手機游戲配置主要看哪些 發布:2025-07-18 17:00:47 瀏覽:148
微課源碼 發布:2025-07-18 16:34:44 瀏覽:1001
壓縮長抱枕 發布:2025-07-18 16:13:38 瀏覽:505
如何使用wifi熱點配置網路 發布:2025-07-18 16:06:25 瀏覽:970