Resumo
- O Windows Sockets 1.1 deu aos programadores do Windows uma interface TCP/IP inspirada em Berkeley, mas não podia transplantar sem mudanças o comportamento bloqueante de Berkeley para o Windows de 16 bits.
- Uma chamada Winsock bloqueada precisava continuar distribuindo mensagens do Windows. O desktop cooperativo seguia respondendo, com limites rigorosos para chamadas aninhadas, reentrância e duração dos buffers.
A chamada de socket deveria esconder a rede
Um socket dá ao programa uma forma estável de enviar e receber dados sem prendê-lo ao fornecedor da pilha de rede subjacente. Era esse o acordo que os desenvolvedores do Windows buscavam. Também queriam começar por um modelo conhecido: os sockets de Berkeley já eram o padrão de programação TCP/IP no Unix.
O projeto Windows Sockets começou em uma sessão Birds of a Feather na Interop ’91, em San José, em 10 de outubro de 1991. A especificação 1.1 registra o que veio depois: um comitê, debates por e-mail, um rascunho que aproveitou amplamente propostas da JSB e da NetManage, uma reunião organizada pela Microsoft em dezembro e um grupo de trabalho que continuou aperfeiçoando o documento. Foi uma interface construída por um grupo, não um protocolo TCP/IP imposto por um único fornecedor.
A versão 1.0 foi publicada para que fornecedores de software de rede e desenvolvedores de aplicativos pudessem começar a criar implementações e programas sob um contrato comum. A versão 1.1, datada de 20 de janeiro de 1993, trouxe esclarecimentos e pequenos ajustes com base na experiência das empresas que haviam implementado a 1.0. A sequência importa: antes de fechar o texto seguinte, o grupo já o havia confrontado com código em execução.
A especificação adotou o modelo de sockets de Berkeley para parecer familiar aos programadores de Unix e facilitar a portabilidade do código-fonte. Definiu a suíte de protocolos da Internet, com sockets de fluxo TCP e sockets de datagrama UDP. Não fingiu que a versão 1.1 padronizava todas as redes possíveis. Esse limite era útil: os desenvolvedores ganhavam uma interface conhecida, sem a promessa de que todo sistema abaixo dela se comportaria igual.
Então recv encontrou o desktop de 16 bits
A parte difícil aparece quando um programa espera. Um recv bloqueante não retorna até que os dados cheguem ou a operação seja resolvida de outra forma. Em um sistema com escalonamento preemptivo, o sistema operacional pode executar outras tarefas enquanto aquele processo espera. O Windows Sockets 1.1 não podia presumir esse tipo de escalonamento no Windows de 16 bits.
A documentação da Microsoft descreve a solução em detalhe incomum. Se uma operação bloqueante não pudesse terminar de imediato, o provedor iniciava a operação e entrava em um loop: distribuía mensagens do Windows, verificava se a chamada de socket havia terminado e repetia. Assim, o aplicativo orientado a mensagens podia continuar processando eventos das janelas enquanto a leitura de rede permanecia pendente.
Esse desenho não transformava um programa de 16 bits em um processo com escalonamento preemptivo. Ele inseria a distribuição de mensagens do Windows em uma chamada que o programador poderia tratar como uma simples espera. Mensagens recebidas durante a espera podiam levar o aplicativo a fazer outra chamada Winsock. A versão 1.1 proibia esse aninhamento: uma tarefa podia ter apenas uma chamada Winsock pendente. Uma segunda chamada aninhada falhava com WSAEINPROGRESS.
A API oferecia duas pequenas saídas. WSAIsBlocking permitia verificar se havia uma chamada bloqueada. WSACancelBlockingCall podia cancelá-la. Aplicativos mais complexos, inclusive os com várias janelas de documentos, podiam instalar WSASetBlockingHook e substituir a rotina padrão de distribuição de mensagens. O aplicativo ganhava controle, junto com a obrigação de processar as mensagens corretamente.
A interface deslocou o trabalho; não o apagou
Chamadas não bloqueantes e assíncronas evitavam o problema de reentrância do bloqueio. Elas traziam outra obrigação. Se uma operação mantivesse um ponteiro para um buffer ou outro objeto de memória, o aplicativo precisava mantê-lo válido até a conclusão. A biblioteca de rede não podia decidir por ele quando aquela memória deixaria de ser necessária.
Essa é a pequena, mas decisiva, lacuna entre uma API familiar e um programa portável. Nomes de funções compatíveis podem reduzir o custo inicial da portabilidade. Não apagam o modelo de escalonamento do sistema anfitrião, seu loop de mensagens ou a vida útil da memória. A Microsoft documentou depois os arquivos de cabeçalho fornecidos para facilitar a portabilidade de código BSD, e manteve as declarações antigas de Winsock.h para compatibilidade com aplicativos existentes após o Winsock 2 introduzir Winsock2.h. A própria compatibilidade virou software que precisava ser carregado adiante.
A versão 1.1 traçou seu limite na interface e nos tipos de socket TCP/IP que definia. Os fornecedores entregavam as implementações; os desenvolvedores de aplicativos escolhiam como esperar, cancelar, distribuir mensagens e proteger a memória. A especificação comum facilitou a conexão dessas peças. Não tornou suas responsabilidades intercambiáveis.
A escolha de engenharia marcante não foi o Windows copiar Berkeley. Foi o grupo preservar vocabulário suficiente de Berkeley para tornar a portabilidade atraente e, ao mesmo tempo, documentar onde o Windows não podia fingir que era Unix. O loop de mensagens foi o recibo: uma interface aberta reduziu um custo e mostrou exatamente onde o próximo apareceu.
Fontes
Briefing para membros
Contexto aprofundado do perfil
Faça login com o nível de assinatura correto para desbloquear o briefing completo e as notas das fontes.
Exclusivo para o Círculo Estratégico
Strategic Circle
Aberto a todos os leitores. Desbloqueie Briefings de perfil após se inscrever e fazer login.
Junte-se ao Strategic CircleSomente para Leadership Alliance
Leadership Alliance
Para proprietários e gestores qualificados de ativos de PI; faça login para desbloquear os briefings da Leadership Alliance.
Junte-se ao Leadership Alliance





