Linux UDP socket 設置為的非阻塞模式與阻塞模式區別
UDP socket 設置為的非阻塞模式
1
|
Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), MSG_DONTWAIT, (struct sockaddr *)&SockAddr,&ScokAddrLen); |
UDP socket 設置為的阻塞模式
1
|
Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), 0, (struct sockaddr *)&SockAddr,&ScokAddrLen); |
Linux socket編程之阻塞套接字和非阻塞套接字
每一個TCP套接口有一個發送緩沖區,可以用SO_SNDBUF套接口選項來改變這個緩沖區的大小。當應用進程調用 write時,內核從應用進程的緩沖區中拷貝所有數據到套接口的發送緩沖區。如果套接口的發送緩沖區容不下應用程序的所有數據(或是應用進程的緩沖區大于套接口發送緩沖區,或是套接口發送緩沖區還有其他數據),應用進程將被掛起(睡眠)。這里假設套接口是阻塞的,這是通常的缺省設置。內核將不從write系統調用返回,直到應用進程緩沖區中的所有數據都拷貝到套接口發送緩沖區。因此從寫一個TCP套接口的write調用成功返回僅僅表示我們可以重新使用應用進程的緩沖區。它并不告訴我們對端的 TCP或應用進程已經接收了數據。
TCP取套接口發送緩沖區的數據并把它發送給對端TCP,其過程基于TCP數據傳輸的所有規則。對端TCP必須確認收到的數據,只有收到對端的ACK,本端TCP才能刪除套接口發送緩沖區中已經確認的數據。TCP必須保留數據拷貝直到對端確認為止。
1 輸入操作: read、readv、recv、recvfrom、recvmsg
如果某個進程對一個阻塞的TCP套接口調用這些輸入函數之一,而且該套接口的接收緩沖區中沒有數據可讀,該進程將被投入睡眠,直到到達一些數據。既然 TCP是字節流協議,該進程的喚醒就是只要到達一些數據:這些數據既可能是單個字節,也可以是一個完整的TCP分節中的數據。如果想等到某個固定數目的數據可讀為止,可以調用readn函數,或者指定MSG_WAITALL標志。
既然UDP是數據報協議,如果一個阻塞的UDP套接口的接收緩沖區為空,對它調用輸入函數的進程將被投入睡眠,直到到達一個UDP數據報。
對于非阻塞的套接口,如果輸入操作不能被滿足(對于TCP套接口即至少有一個字節的數據可讀,對于UDP套接口即有一個完整的數據報可讀),相應調用將立即返回一個EWOULDBLOCK錯誤。
2 輸出操作:write、writev、send、sendto、sendmsg
對于一個TCP套接口,內核將從應用進程的緩沖區到該套接口的發送緩沖區拷貝數據。對于阻塞的套接口,如果其發送緩沖區中沒有空間,進程將被投入睡眠,直到有空間為止。
對于一個非阻塞的TCP套接口,如果其發送緩沖區中根本沒有空間,輸出函數調用將立即返回一個EWOULDBLOCK錯誤。如果其發送緩沖區中有一些空間,返回值將是內核能夠拷貝到該緩沖區中的字節數。這個字節數也稱為不足計數(short count)
UDP套接口不才能在真正的發送緩沖區。內核只是拷貝應用進程數據并把它沿協議棧向下傳送,漸次冠以UDP頭部和IP頭部。因此對一個阻塞的UDP套接口,輸出函數調用將不會因為與TCP套接口一樣的原因而阻塞,不過有可能會因其他的原因而阻塞。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
原文鏈接:http://www.cnblogs.com/lidabo/p/6039677.html