1. 程式人生 > >Tcp Socket非阻塞recv

Tcp Socket非阻塞recv

最近看了許多關於網路程式設計的資料,自己小記一下,以方便以後查詢。

什麼是阻塞socket,什麼是非阻塞socket。對於這個問題,我們要先弄清什麼是阻塞/非阻塞。阻塞與非阻塞是對一個檔案描述符指定的檔案或裝置的兩種工作方式。 阻塞的意思是指,當試圖對該檔案描述符進行讀寫時,如果當時沒有東西可讀或者暫時不可寫,程式就進入等待狀態,直到有東西可讀或者可寫為止。 非阻塞的意思是,當沒有東西可讀或者不可寫時,讀寫函式就馬上返回,而不會等待。

這裡我列舉了,哪些socket api會阻塞:

accept,connect,recv(recvfrom),send(sendto),closesocket,select(poll或epoll)

1)accept在阻塞模式下,沒有新連線時,執行緒會進入睡眠狀態;非阻塞模式下,沒有新連線時,立即返回WOULDBLOCK錯誤。

2)connect在阻塞模式下,僅TCP連線建立成功或出錯時才返回,分幾種具體的情況,這裡不再敘述;非阻塞模式下,該函式會立即返回INPROCESS錯誤(需用select檢測該連線是否建立成功)

3)recv/recvfrom/send/sendto很好理解,因為這兩類函式讀寫socket檔案描述符的接收/傳送緩衝區。

4) select/poll/epoll並不是真正意義上的阻塞,它們的阻塞是由於它們最後一個timeout引數決定的,timeout大於0時,它們會一直等待直到超時才退出(相等於阻塞了吧,^_^),而timeout=-1即永遠等待。

5)closesocket也不是真正意義上的阻塞,它其實是指是否等待關閉(相當於阻塞了吧,^_^),它受套接字選項SO_LINGER和SO_DONTLINGER的影響。

若SO_DONTLINGER或SO_LINGER的間隔=0時,closesocket就是非等待關閉的,但是當SO_LINGER的間隔>0時,closesoket就是等待關閉的,直到剩餘資料都發送完畢或直到超時才退出。

(但是這個地方只有對於阻塞的套接口才有用,如果是非阻塞的套介面,它會立即返回並且指示錯誤WOULDBLOCK)。

例項:

客戶端讀操作:

 1 BOOL CCommunication::InitCom()
 2 {
 3     WORD wVersionRequested;
 4     WSADATA wsaData;
 5     int err;
 6     CString szMsg;
7 m_tcpPort.TrimLeft(); 8 m_tcpPort.TrimRight(); 9 10 int port = atoi(m_tcpPort); 11 12 wVersionRequested = MAKEWORD(1,1); 13 14 err = WSAStartup(wVersionRequested,&wsaData); 15 if (err != 0) 16 { 17 return FALSE; 18 } 19 20 if (LOBYTE(wsaData.wVersion) != 1 || 21 HIBYTE(wsaData.wVersion) != 1) 22 { 23 WSACleanup(); 24 return FALSE; 25 } 26 27 m_clientSocket = socket(AF_INET,SOCK_STREAM,0); 28 if (m_clientSocket == INVALID_SOCKET) 29 { 30 TRACE("建立套接字失敗!"); 31 return FALSE; 32 } 33 34 SOCKADDR_IN addrClient; 35 addrClient.sin_addr.S_un.S_addr = inet_addr(m_szLocalPort); 36 addrClient.sin_family = AF_INET; 37 addrClient.sin_port = htons(port); 38 memset(addrClient.sin_zero,0,sizeof(addrClient.sin_zero)); 39 m_connsocket = connect(m_clientSocket,(SOCKADDR*)&addrClient,sizeof(SOCKADDR)); 40 if (m_connsocket == SOCKET_ERROR) 41 { 42 TRACE("Connect Error!"); 43 return FALSE; 44 } 45 DWORD nMode = 1; 46 int nError = ioctlsocket(m_clientSocket,FIONBIO,&nMode); 47 if (nError == SOCKET_ERROR) 48 { 49 closesocket(m_clientSocket); 50 WSACleanup(); 51 return FALSE; 52 } 53 return TRUE; 54 } 55 56 int CCommunication::ReadBytes(BYTE *lpByte, DWORD dwBytes) 57 { 58 tv.tv_sec = 2; 59 tv.tv_usec = 0; 60 FD_ZERO(&fdRead); 61 FD_SET(m_clientSocket,&fdRead); 62 63 int nError = select(0,&fdRead,NULL,NULL,&tv); 64 if (nError <= 0) 65 { 66 return 0; 67 } 68 if (FD_ISSET(m_clientSocket,&fdRead)) 69 { 70 memset(lpByte,0,dwBytes); 71 nError = recv(m_clientSocket,(char*)lpByte,dwBytes,0); 72 } 73 74 75 return nError; 76 }

相關推薦

Tcp Socket阻塞recv

最近看了許多關於網路程式設計的資料,自己小記一下,以方便以後查詢。 什麼是阻塞socket,什麼是非阻塞socket。對於這個問題,我們要先弄清什麼是阻塞/非阻塞。阻塞與非阻塞是對一個檔案描述符指定的檔案或裝置的兩種工作方式。 阻塞的意思是指,當試圖對該檔案描述符進行讀寫時,

socket阻塞模組

一 服務端程式 # 匯入模組 import socketserver import random # 定義一個類 class MyServer(socketserver.BaseRequestHandler): # 如果handle方法出現報錯,則會進行跳過 #

NIO實現TCP阻塞通訊

這一次寫NIO實現非阻塞通訊時遇到了很多問題,我所理解的非阻塞是對於一個使用者而言它的讀寫不會相互制約,而在此次編寫過程中,發現其實非阻塞是相對於多個使用者而言的。 看到網上一個對同步非同步阻塞非阻塞的例子,感覺挺好的,就拷過來了: 老張愛喝茶,廢話不說

Java簡單實現Socket阻塞通訊

        用java實現socket C/S通訊很簡單,很多教科書上都有。但是這些通訊模型大都是阻塞式的,其弊端也很明顯:一方必須要接收的到對方的訊息後,才能編輯自己的訊息發出。同樣對方也要一直等待這條訊息收到後才能傳送新的訊息。用網路通訊的知識講,大概就是半雙工通訊

epoll關於ET、LT模式和socket阻塞模式的幾個總結

epoll的ET和LT模式 LT水平觸發是預設的模式,只要緩衝區有訊息就會觸發,如果這次事件沒有被處理,那麼下一次呼叫epoll_wait的時候,事件仍然會被觸發;ET邊沿觸發只會在第一次有訊息的時候觸發,之後再次呼叫epoll_wait的時候,事件不會被再次觸發了。Linux的ep

Windows Socket 阻塞模式開發

                                                                  非阻塞套接字            非阻塞模式是指:套接字在執行操作時,呼叫的函式不管操作是否完成都會立即返回的工作模式。     非阻塞套接字在處理同時建立的多個連線等方面具

boost庫之socket 阻塞/緩衝區大小等屬性設定

asio socket 非阻塞/緩衝區大小等屬性設定ip::tcp::socket m_socket  //設定阻塞與非阻塞void SetNoBlock(bool bNoBlock){ if(bNoBlock) {  boost::asio::socket_base::by

TCP阻塞connect和accept

套接字的預設狀態是阻塞的,這就意味著當發出一個不能立即完成的套接字呼叫時,其程序將被投入睡眠,等待響應操作完成,可能阻塞的套接字呼叫可分為以下四類: (1) 輸入操作,包括read,readv,recv,recvfrom,recvmsg; (2) 輸出操作,包括write,writev,send,sendt

socket程式設計中send recv阻塞阻塞詳解

int send( SOCKET s, const char FAR *buf, int len, int flags ); 不論是客戶還是伺服器應用程式都用send函式來向TCP連線的另一端傳送資料。客戶程式一般用send函式向伺服器傳送請求,而伺服器則通常用send函

關於socket阻塞阻塞情況下的recv、send、read、write返回值

recv: 阻塞與非阻塞recv返回值沒有區分,都是 <0:出錯,=0:連線關閉,>0接收到資料大小, 特別:非阻塞模式下返回 值 <0時並且(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAI

TCP阻塞socket程式設計

網路通訊程式的同步方式指的是傳送方不等接收方響應,便接著發下個數據包的通訊方式;而非同步指傳送方發出資料後,等收到接收方發回的響應,才發下一個數據包的通訊方式。 阻塞套接字是指執行此套接字的網路呼叫時,直到成功才返回,否則一直阻塞在此網路呼叫上,比如呼叫recv()函式讀取網

Socket編程中,阻塞阻塞的區別

軟件 復用 優點 調用 服務器 運用 需要 默認 con   阻塞:一般的I/O操作可以在新建的流中運用.在服務器回應前它等待客戶端發送一個空白的行.當會話結束時,服務器關閉流和客戶端socket.如果在隊列中沒有請示將會出現什麽情況呢?那個方法將會等待一個的到來.這個行為

異步阻塞socket的實現

print except 事件循環 port int 性能 run utf8 try 在學習使用scrapy爬蟲框架之前,需要了解一些基礎原理   我們知道HTTP請求是基於socket模塊進行發送和接受的,但是socket套接字的在使用的中存在著阻塞,不利用爬蟲的高性能運

設置阻塞的套接字Socket

api pad def while循環 ace 使用方法 小時 acc 使用 當使用socket()函數和WSASocket()函數創建套接字時,默認都是阻塞的。在創建套接字之後,通過調用ioctlsocket()函數,將該套接字設置為非阻塞模式。函數的第一個參數是套接字

Linux Socket - 內核阻塞功能

由於 有變 增加 連接建立 ioc eval type ddr ont select 函數 int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval*time

服務器編程心得(四)—— 如何將socket設置為阻塞模式

led -h bsp wait per 設置 inux sign 也有 1. windows平臺上無論利用socket()函數還是WSASocket()函數創建的socket都是阻塞模式的: SOCKET WSAAPI socket( _In_ int af,

scala通過akka的actor實現socket http server(NIO阻塞模式)

1首先是sbt需要匯入的依賴 name := "HttpServer" version := "1.0" scalaVersion := "2.11.8" libraryDependencies ++= Seq( "com.typesafe.akka" %% "akka-act

阻塞socket

非阻塞的socket 同步和非同步的概念描述的是使用者執行緒與核心的互動方式:同步是指使用者執行緒發起IO請求後需要等待或者輪詢核心IO操作完成後才能繼續執行;而非同步是指使用者執行緒發起IO請求後仍繼續執行,當核心IO操作完成後會通知使用者執行緒,或者呼叫使用者執行緒註冊的回撥函式。

recv send 阻塞阻塞

int send( SOCKET s, const char FAR *buf, int len, int flags ); 不論是客戶還是伺服器應用程式都用send函式來向TCP連線的另一端傳送資料。客戶程式一般用send函式向伺服器傳送請求,而伺服器則通常用send函式來向客戶程式傳送應答。

C/C++網路程式設計在windows和linux中將socket設定為阻塞阻塞

C/C++網路程式設計在windows和linux中將socket設定為阻塞和非阻塞              在 socket程式設計中,對於socket的讀寫預設都是阻塞的,但有的情況我們需要將其設定為非阻塞,比如做多