5

MSDNによると: Listen() はブロッキング呼び出しです。listen() を使用した関数のコード スニペットを以下に示します。

sockaddr_in addr    = {0};
int     addrlen = sizeof(addr);
SOCKET  sock_listen;

if(-1 == (sock_listen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)))
{
    cout<<"error";
}   

addr.sin_family = AF_INET;
/* Network byte ordered address for loopback */
addr.sin_addr.s_addr= inet_addr("127.0.0.1");
/* Let service provider assign a unique port from dynamic client port range */  
addr.sin_port   = 0;                        

if(-1 == bind(sock_listen, (const sockaddr *)&addr, addrlen))       
{
    CloseHandle((HANDLE)sock_listen_fd);
    cout<<"error";
}

if(-1 == getsockname(sock_listen, (sockaddr *)&addr, &addrlen))
{     
    CloseHandle((HANDLE)sock_listen);
    cout<<"error";
}

u_long mode = 0;
if(SOCKET_ERROR == ioctlsocket(sock_listen, FIONBIO, &mode))
{
    cout<<"ioctl failed";
}

if(SOCKET_ERROR == listen(sock_listen, 1))
{
    cout<<"listen error";
}
cout<<"Passed listen";
if(SOCKET_ERROR == (s = ACL_accept(sock_listen_fd, NULL, NULL)))
{
       cout<<"accept error";
}

デフォルトでは、ブロッキング タイプとして作成されたソケット ハンドル。さらに確実にするために、ioctlsocket() を呼び出して、ソケット ハンドルをブロック型にします。

出力は次のとおりです。

したがって、スレッドは listen() でブロックされていません。代わりに、私の知る限り、正しい方法である受け入れでブロックされます。Linux MANページでも明確に説明されています:

listen() は、socket fd によって参照されるソケットをパッシブソケット、つまり、accept() を使用して着信接続要求を受け入れるために使用されるソケットとしてマークします。

では、MSDN がリッスンは Winsock 呼び出しをブロックしていると言っているのはなぜですか。それらは、何らかのイベントを内部で待機していることを意味しますか?

4

3 に答える 3

2

OS が、呼び出しスレッドがソケットへの排他的アクセスを持っていることを確認する必要があるという意味では、ブロッキング呼び出しである可能性があります。これには、ある種のロックが必要であり、他のスレッドがそのロックを保持している場合、呼び出し元をブロックする可能性があります。 .

編集 0:

一般に、オペレーティングシステムへの呼び出しは、他の優先度の高い処理を優先してユーザーランドスレッドのスケジュールを解除する機会です。ただし、これは通常「ブロッキング」とは呼ばれず、「スリープ」または「プリエンプト」と呼ばれます。

于 2013-05-21T12:16:52.543 に答える
1

MSDN がそう言っているのであれば、それは誤りです。ブロッキングコールではありません。ブロックするものは何もありません。確かに「外部ネットワーク イベント」はありません。

そう言っているパラグラフは明らかにボイラープレートがあまりにも多くの場所にコピーされています.

于 2013-05-21T12:16:55.497 に答える