Windows Sockets: bloquear
Este artigo e dois artigos complementares explicam vários problemas na programação do Windows Sockets. Este artigo aborda o bloqueio. Os outros problemas são abordados nos artigos: Windows Sockets: Ordenação de bytes e Windows Sockets: Conversão de cadeia de caracteres.
Se você usar ou derivar da classe CAsyncSocket, precisará gerenciar esses problemas por conta própria. Se você usar ou derivar da classe CSocket, o MFC os gerenciará para você.
Bloqueio
Um soquete pode estar no "modo de bloqueio" ou no "modo sem bloqueio". As funções de soquetes no modo de bloqueio (ou síncrono) não retornam até que possam concluir sua ação. Isso é chamado de bloqueio porque o soquete cuja função foi chamada não pode fazer nada (está bloqueado) até que a chamada retorne. Uma chamada para a função de membro Receive
, por exemplo, pode levar muito tempo para ser concluída arbitrariamente enquanto aguarda o envio do aplicativo de envio (isto é, se você estiver usando CSocket
ou usando CAsyncSocket
com bloqueio). Se um objeto CAsyncSocket
estiver no modo de desbloqueio (operando de forma assíncrona), a chamada retornará imediatamente e o código de erro atual, recuperável com a função de membro GetLastError, será WSAEWOULDBLOCK, indicando que a chamada teria bloqueado se ela não tivesse retornado imediatamente por causa do modo. (CSocket
nunca retorna WSAEWOULDBLOCK. A classe gerencia o bloqueio para você.)
O comportamento dos soquetes é diferente em sistemas operacionais de 32 bits e 64 bits (como Windows 95 ou Windows 98) do que em sistemas operacionais de 16 bits (como Windows 3.1). Ao contrário dos sistemas operacionais de 16 bits, os sistemas operacionais de 32 e 64 bits usam multitarefas preventivas e fornecem multithreading. Nos sistemas operacionais de 32 bits e 64 bits, você pode colocar seus soquetes em threads de trabalho separados. Um soquete em um thread pode ser bloqueado sem interferir em outras atividades em seu aplicativo e sem gastar tempo de computação no bloqueio. Para obter informações sobre programação multithreaded, consulte o artigo Multithreading.
Observação
Em aplicativos multithreaded, você pode usar a natureza de bloqueio de CSocket
para simplificar o design do programa sem afetar a capacidade de resposta da interface do usuário. Ao manipular as interações do usuário no thread principal e o processamento de CSocket
em threads alternativos, você pode separar essas operações lógicas. Em um aplicativo que não é multithread, essas duas atividades devem ser combinadas e tratadas como um único thread, o que geralmente significa usar CAsyncSocket
para que você possa lidar com solicitações de comunicação sob demanda ou substituir CSocket::OnMessagePending
para lidar com ações do usuário durante uma atividade síncrona demorada.
O restante desta discussão é para programadores direcionados a sistemas operacionais de 16 bits:
Normalmente, se você estiver usando CAsyncSocket
, evite usar operações de bloqueio e opere de forma assíncrona. Em operações assíncronas, a partir do ponto em que você recebe um código de erro WSAEWOULDBLOCK após chamar Receive
, por exemplo, você aguarda até que sua função de membro OnReceive
seja chamada para notificá-lo de que você pode ler novamente. Chamadas assíncronas são feitas chamando de volta a função de notificação de retorno de chamada apropriada do soquete, como OnReceive.
No Windows, o bloqueio de chamadas é considerado uma má prática. Por padrão, CAsyncSocket dá suporte a chamadas assíncronas e você deve gerenciar o bloqueio usando notificações de retorno de chamada. A classe CSocket, por outro lado, é síncrona. Ele envia mensagens do Windows e gerencia o bloqueio para você.
Para obter mais informações sobre o bloqueio, consulte a especificação do Windows Sockets. Para obter mais informações sobre funções "Ativadas", consulte Windows Sockets: Notificações de soquetes e Windows Sockets: Derivando de classes de soquete.
Para saber mais, veja: