當前位置:編程學習大全網 - 編程語言 - recv是阻塞還是非阻塞的

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設置成非阻塞模式。

  • 上一篇:濟南易途java培訓怎麽樣?學費多少?
  • 下一篇:開發壹個app購物平臺需要多少錢
  • copyright 2024編程學習大全網