Compartilhar via


Soquetes do Windows: Bloqueio

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: Soquetes do Windows: Ordenação de Bytes e Soquetes do Windows: Convertendo cadeias 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 a 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 CAsyncSocket objeto estiver no modo de não 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 não tivesse retornado imediatamente devido ao 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 o Windows 3.1). Ao contrário dos sistemas operacionais de 16 bits, os sistemas operacionais de 32 bits e 64 bits usam multitarefas preemptivas 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 é multithreaded, 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 longa.

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, o CAsyncSocket dá suporte a chamadas assíncronas e você deve gerenciar o bloqueio por conta própria 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 de Soquetes do Windows. 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 obter mais informações, consulte:

Consulte também

Soquetes do Windows no MFC
CAsyncSocket::OnSend