Há cerca de 18 meses, escrevi um blog falando sobre mudanças na forma de aceitação do OpenVOS release 17.1. O que eu negligenciei em indicar foi que estas mudanças só têm efeito se o código da aplicação for baseado no POSIX. Recapitulando, antes da 17.1 STCP só responderia a um pedido de conexão de cliente se o código de aplicação do servidor tivesse chamado a rotina de aceitação. Se o código não tivesse chamado aceitar o pedido de conexão do cliente entraria em uma fila, mas não seria atendido. Uma vez que a aplicação chamada aceitasse, o STCP enviaria uma resposta de conexão. Se o cliente ainda estiver aguardando, a conexão será concluída naquele momento. Se o cliente já tivesse desistido, ele responderia à resposta da conexão com um reset, a STCP jogaria a conexão fora e a aceitação seria suspensa (assumindo o modo de bloqueio) e esperaria por outra conexão.
A Figura 1 mostra este cenário; as linhas de texto justificadas à esquerda são mensagens de status da aplicação do servidor, as linhas de pacote_monitor recuado (ligeiramente modificadas) são o resultado da atividade do cliente. A aplicação (acceptTestnoPosix) é iniciada e escuta na porta 12345, e uma vez ouvida, dorme por 300 segundos. O cliente então faz uma conexão à porta 12345 enviando um segmento TCP para a porta 12345 com a bandeira Syn (S) configurada. Ele tenta três vezes antes de desistir. Após 300 segundos, o aplicativo acorda e as chamadas são aceitas. O stack STCP responde ao cliente com um segmento TCP com as bandeiras Syn e Ack (SA) configuradas. Como o cliente não tem mais um registro da conexão se enviar um Reset (R), o STCP bloqueia neste ponto. Se o soquete estivesse em modo não-bloqueio, o aceite teria retornado com um erro EAGAIN.
acceptTestnoPosix 12345 Executando acceptTestnoPosix 12345 Dormir por 300 segundos 11:04:45.923 R TCP 164.152.77.50 164.152.77.217 11071 12345 S 11:04:48.925 R TCP 164.152.77.50 164.152.77.217 11071 12345 S 11:04:54.937 R TCP 164.152.77.50 164.152.77.217 11071 12345 S Pronto para aceitar uma conexão na porta número 12345 11:09:41.852 TCP 164.152.77.217 164.152.77.77.50 12345 11071 SA 11:09:41.854 R TCP 164.152.77.50 164.152.77.217 11071 12345 R |
Figura 1 - aceitar pré 17.1 ou pós 17.1 não-POSIX
Se a aplicação for baseada no POSIX, as coisas são diferentes (Figura 2). STCP responde ao pedido de conexão (S) imediatamente (SA). Depois de 300 segundos, a aplicação acorda, as chamadas são aceitas e a STCP retorna o soquete aceito.
acceptTestwithPosix 12345 Executando acceptTestnoPosix 12345 Dormir por 300 segundos 10:58:43.962 R TCP 164.152.77.50 164.152.77.217 11024 12345 S 10:58:43.964 TCP 164.152.77.217 164.152.77.77.50 12345 11024 SA 10:58:43.964 R TCP 164.152.77.50 164.152.77.217 11024 12345 A Pronto para aceitar uma conexão na porta número 12345 Conexão aceita |
Figura 2 - aceitar POSIX com base no poste 17.1
A diferença de comportamento pode ser crítica. Se o cliente estiver esperando uma resposta da aplicação do servidor após fazer uma conexão, ele pode demorar e fechar a conexão antes que a aplicação realmente aceite as chamadas.
Como você constrói uma aplicação com o POSIX? Primeiro a linha
#define _POSIX_C_SOURCE 200112L |
deve ser a primeira linha da fonte de aplicação. Segundo o caminho da biblioteca
(disco_mestre)>sistema>biblioteca_de_objectos_de_posixos
precisa estar nos caminhos da biblioteca de objetos depois das bibliotecas STCP e antes da biblioteca C.
Como você pode saber se isso foi feito? Bem, você pode olhar para as bibliotecas de objetos com as quais a aplicação foi ligada usando o comando display_program_module -object_dirs
display_program_module acceptTestwithPosix -object_dirs
%azvos#m17_mas>SysAdmin>Noah_Davids>temp>acceptTestwithPosix.pm
Mapa de Diretório de Objetos:
11 diretórios de busca
0 diretórios sem pesquisa
11 diretórios no total
DTC Directory Path
1 %azvos#m17_mas>SysAdmin>Noah_Davids>temp
2 %azvos#m17_mas>sistema>stcp>object_library
3 %azvos#m17_mas>sistema>stcp>object_library>socket
4 %azvos#m17_mas>sistema>stcp>object_library>net
5 %azvos#m17_mas>sistema>stcp>object_library>common
6 %azvos#m17_mas>sistema>biblioteca_de_objectosposix
7 %azvos#m17_mas>sistema>c_objecto_biblioteca
8 %azvos#m17_mas>sistema>objecto_biblioteca
9 %azvos#m17_mas>opt>apache>lib
10 %azvos#m17_mas>opt>openssl>lib
11 %azvos#m17_mas>opt>mysql>lib>mysql
|
Mas isto não lhe diz se o #define faz parte do código fonte.
Se você puder executar o código, você pode olhar para as bandeiras do soquete, um programa baseado no POSIX terá o conjunto de bandeiras de soquete SF_POSIX. Por exemplo, tenho três programas aceitandoTestnoPosix, aceitandoTestwithPosix e aceitandoTestwithPosixPathOnly. Este último tinha o >system>posix_object_library directory nos caminhos da biblioteca mas não incluía o #define no código fonte. Note que esta é considerada uma combinação inválida. Somente a aplicação que estava ligada à biblioteca POSIX e tinha a declaração POSIX_SOURCE #define no código criou um socket com a bandeira SF_POSIX.
acceptTestnoPosix.pm 12345 Executando acceptTestnoPosix 12345 Dormir por 300 segundos como: match posix; dump_stcbq -full -lport 12345 como: |
acceptTestwithPosix.pm 12345
Executando acceptTestnoPosix 12345
Dormir por 300 segundos
como: match posix; dump_stcbq -full -lport 12345
SF_POSIX
como:
|
acceptTestwithPosixPathOnly.pm 12345 Executando acceptTestnoPosix 12345 Dormir por 300 segundos como: match posix; dump_stcbq -full -lport 12345 como: |
Existe uma quarta possibilidade, o #define foi incluído na fonte mas a biblioteca posix_object_library não foi utilizada. Neste caso, a rotina do soquete retornará um erro.
acceptTestwithPosixDefineOnly 12345 Executando acceptTestnoPosix 12345 acceptTestnoPosix: não pode criar soquete de escuta: Aplicação construída + incorretamente: O tempo de execução POSIX deve ser pesquisado antes do tempo de execução C. |
Todos os comandos e utilitários STCP são construídos com o POSIX e eu recomendo fortemente que quaisquer aplicações que você construa também utilizem o POSIX.