Indy em Profundidade
Indy em Profundidade
Página 1
Indy em Profundidade
https://translate.googleusercontent.com/translate_f 1/261
22/04/2020 Indy em Profundidade
Página 2
https://translate.googleusercontent.com/translate_f 2/261
22/04/2020 Indy em Profundidade
Indy
Domando o desenvolvimento da Internet, um protocolo por vez.
https://translate.googleusercontent.com/translate_f 3/261
22/04/2020 Indy em Profundidade
Page 3
Indy em Profundidade
Todos os direitos reservados. Nenhuma parte deste trabalho pode ser reproduzida de nenhuma forma ou por qualquer meio - gráfico, eletrônico ou
sistemas mecânicos, incluindo fotocópia, gravação, gravação ou armazenamento e recuperação de informações - sem a
permissão por escrito do editor.
Os produtos mencionados neste documento podem ser marcas comerciais e / ou marcas comerciais registradas da
respectivos proprietários. O editor e o autor não reivindicam essas marcas registradas.
https://translate.googleusercontent.com/translate_f 4/261
22/04/2020 Indy em Profundidade
Embora tenham sido tomadas todas as precauções na preparação deste documento, o editor e o autor não assumem
responsabilidade por erros ou omissões ou por danos resultantes do uso das informações contidas neste documento
ou do uso de programas e código fonte que possam acompanhá-lo. Em nenhum caso o editor e o autor devem ser
responsável por qualquer perda de lucro ou qualquer outro dano comercial causado ou supostamente causado diretamente ou
indiretamente por este documento.
Se uma licença pessoal tiver sido comprada, este documento, seu conteúdo e todo o código de amostra associado serão licenciados apenas
para uso pelo indivíduo para o qual foi licenciado. Não pode ser compartilhado ou distribuído para outras pessoas.
A empresa pode redistribuir este documento e o código-fonte associado se o acesso for restrito apenas a funcionários
e empreiteiros atuais da corporação.
https://translate.googleusercontent.com/translate_f 5/261
22/04/2020 Indy em Profundidade
Page 4
Eu Indy em Profundidade
Índice
Prefácio 00
Parte I Introdução 11
1 Sobre o livro .................................................. .................................................. ............................... 11
Comentários .................................................. .................................................. .................................................. .... 11
Atualizações .................................................. .................................................. .................................................. .... 11
Demonstrações .................................................. .................................................. .................................................. .... 11
3 Informações adicionais
.................................................. .................................................. ............................... 13
Outros recursos .................................................. .................................................. .................................................. .... 14
Leitura adicional .................................................. .................................................. .................................................. .... 14
https://translate.googleusercontent.com/translate_f 6/261
22/04/2020 Indy em Profundidade
5 Relatórios de erros
.................................................. .................................................. ............................... 17
6 Winsock 2 .................................................. .................................................. ............................... 17
Page 5
https://translate.googleusercontent.com/translate_f 7/261
22/04/2020 Indy em Profundidade
Conteúdo II
16 Localhost (Loopback)
.................................................. .................................................. ............................... 23
17 Ping .................................................. .................................................. ............................... 24
18 TraceRoute .................................................. .................................................. ............................... 24
19 LAN .................................................. .................................................. ............................... 25
20 WAN .................................................. .................................................. ............................... 25
21 IETF .................................................. .................................................. ............................... 25
22 RFC .................................................. .................................................. ............................... 25
https://translate.googleusercontent.com/translate_f 8/261
22/04/2020 Indy em Profundidade
10 profissionais de não-bloqueio
.................................................. .................................................. ........................... 33
11 Contras de não-bloqueio
.................................................. .................................................. ........................... 33
12 Comparação .................................................. .................................................. ........................... 33
13 arquivos vs. soquetes
.................................................. .................................................. ............................... 34
II
Page 6
https://translate.googleusercontent.com/translate_f 9/261
22/04/2020 Indy em Profundidade
3 Métodos de Gravação
.................................................. .................................................. ............................... 56
SendCmd .................................................. .................................................. .................................................. .... 57
Page 7
Conteúdo IV
4 Buffer de Gravação
.................................................. .................................................. ............................... 59
5 Transações de Trabalho
.................................................. .................................................. ............................... 59
Eventos OnWork .................................................. .................................................. .................................................. .... 59
Gerenciando suas próprias
... .....transações
..... ..... ..... de
.....trabalho
..... ..... ..... .. ... ..... ..... ..... ..... ..... ..... ..... ..... .. ... ..... ..... ..... .... ..... ..... ..... ..... ..... ... 6 0
https://translate.googleusercontent.com/translate_f 11/261
22/04/2020 Indy em Profundidade
4 EIdConnClosedGracfully
.................................................. .................................................. ............................... 63
Introdução .................................................. .................................................. .................................................. .... 64
Por que essa exceção ocorre
... ..... .....
nos.....
servidores?
..... ..... ..... ..... ..... .. ... ..... ..... ..... ..... ..... ..... ..... ..... .. ... ..... ..... ..... .... ..... ..... ..... ..... ..... ... .. 6 5
Por que é uma exceção?
... ..... ..... ..... ..... ..... ..... ..... ..... .. ... ..... ..... ..... ..... ..... ..... ..... ..... .. ... ..... ..... ..... .... ..... ..... ..... ..... ..... ... .. 6 5
É um erro? .................................................. .................................................. .................................................. .... 65
Quando é um erro? ... ..... ..... ..... ..... ..... ..... ..... ..... .. ... ..... ..... ..... ..... ..... ..... ..... ..... .. ... ..... ..... ..... .... ..... ..... ..... ..... ..... ... .. 6 6
Solução Simples .................................................. .................................................. .................................................. .... 66
6 Definindo um protocolo
..................................................
personalizado .................................................. ............................... 74
7 Simulação de pares
.................................................. .................................................. ............................... 75
IV
Page 8
V Indy em Profundidade
https://translate.googleusercontent.com/translate_f 12/261
22/04/2020 Indy em Profundidade
8 Protocolo do Código
..................................................
Postal .................................................. ............................... 75
Socorro .................................................. .................................................. .................................................. .... 75
Olho para cima .................................................. .................................................. .................................................. .... 76
Sair .................................................. .................................................. .................................................. .... 77
Proxies da Parte XI 79
1 Proxies transparentes
.................................................. .................................................. ............................... 79
Mascaramento de IP / ...
conversão
..... ..... .....
de.....
endereço
..... ..... .....
de rede
..... ..(NAT)
... ..... ..... ..... ..... ..... ..... ..... ..... .. ... ..... ..... ..... .... ..... ..... ..... ..... ..... ... 7 9
Portas / túneis mapeados
... ..... ..... ..... ..... ..... ..... ..... ..... .. ... ..... ..... ..... ..... ..... ..... ..... ..... .. ... ..... ..... ..... .... ..... ..... ..... ..... ..... ... 7 9
Usuário FTP @ Proxy..................................................
do Site .................................................. .................................................. .... 80
2 Simulação de pares
.................................................. .................................................. ............................... 90
3 Gravar e reproduzir
.................................................. .................................................. ............................... 90
Parte XV Concorrência 92
1 Terminologia .................................................. .................................................. ............................... 92
https://translate.googleusercontent.com/translate_f 13/261
22/04/2020 Indy em Profundidade
Concorrência .................................................. .................................................. .................................................. .... 93
Contenção .................................................. .................................................. .................................................. .... 93
Proteção de Recursos .................................................. .................................................. .................................................. .... 93
2 Resolvendo contenção
.................................................. .................................................. ............................... 93
Somente leitura .................................................. .................................................. .................................................. .... 93
Operações atômicas .................................................. .................................................. .................................................. .... 94
Suporte ao sistema operacional
.................................................. .................................................. .................................................. .... 94
Proteção explícita .................................................. .................................................. .................................................. .... 94
Seções críticas .................................................. .................................................. .................................................. ... 95
Nota para usuários padrão. .....
do Delphi
..... .....4..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... .... ..... ..... ..... ..... ..... ..... .. 9 6
TMultiReadExclusiveWriteSynchronizer
..................................................
(TMREWS) .................................................. .................................................. ... 96
Notas especiais sobre TMREWS
. ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... .... ..... ..... ..... ..... ..... ..... .. 9 6
TMREWS no Kylix .................................................. .................................................. ..................................... 96
Escolhendo entre..seções
..... .....críticas
..... .....e .....
TMREWS
..... ..... ..... ..... ... .. ..... ..... ..... ..... ..... ..... ..... ..... ..... ... .. ..... ..... ..... .... ..... ..... ..... ..... ..... .... 9 7
Comparação de desempenho
.................................................. .................................................. .................................................. ... 97
Page 9
Conteúdo VI
https://translate.googleusercontent.com/translate_f 14/261
22/04/2020 Indy em Profundidade
Segurança .................................................. .................................................. .................................................. .... 101
Processadores múltiplos
.................................................. .................................................. .................................................. .... 101
Sem serialização .................................................. .................................................. .................................................. .... 101
12 TIdThreadComponent
.................................................. .................................................. ............................... 104
13 TIdSync .................................................. .................................................. ............................... 104
14 TIdNotify .................................................. .................................................. ............................... 104
15 TIdThreadSafe.................................................. .................................................. ............................... 104
16 Problemas Comuns
.................................................. .................................................. ............................... 105
17 Gargalos .................................................. .................................................. ............................... 105
Implementação de Seção
..... .....
Crítica
..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... .... ..... ..... ..... ..... ...... .... 10 5
TMREWS .................................................. .................................................. .................................................. .... 105
Sincronizações .................................................. .................................................. .................................................. .... 106
Atualizações da interface
..... .....
do.....
usuário
..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... .... ..... ..... ..... ..... ...... .... 10 6
https://translate.googleusercontent.com/translate_f 15/261
22/04/2020 Indy em Profundidade
TIdSimpleServer .................................................. .................................................. .................................................. .... 113
VI
Page 10
2 Eventos Encadeados
.................................................. .................................................. ............................... 114
3 modelos de servidor
..................................................
TCP .................................................. ............................... 114
OnExecute .................................................. .................................................. .................................................. .... 114
Manipuladores de Comando
.................................................. .................................................. .................................................. .... 115
4 Manipuladores..................................................
de Comando .................................................. ............................... 116
Implementação .................................................. .................................................. .................................................. .... 116
Protocolo de exemplo.................................................. .................................................. .................................................. .... 117
Demonstração base .................................................. .................................................. .................................................. .... 117
Criando um manipulador
..... .....de.....
comandos
..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... .... ..... ..... ..... ..... ...... .... 11 7
Suporte ao Manipulador
..... .....
de .....
Comando
..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... .... ..... ..... ..... ..... ...... .... 11 9
Testando o novo comando
..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... .... ..... ..... ..... ..... ...... .... 12 0
Implementando HELP
.................................................. .................................................. .................................................. .... 120
Implementando DATETIME
.................................................. .................................................. .................................................. .... 121
Conclusão .................................................. .................................................. .................................................. .... 123
5 Servidor de código
..................................................
postal - Implementação OnExecute .................................................. ............................... 123
6 Servidor de Código
..................................................
Postal - Manipuladores de ..................................................
Comando ............................... 123
7 Gerenciamento..................................................
de threads .................................................. ............................... 123
TIdThreadMgrDefault
.................................................. .................................................. .................................................. .... 123
Pool de segmentos .................................................. .................................................. .................................................. .... 124
2 Outros Clientes
.................................................. .................................................. ............................... 126
https://translate.googleusercontent.com/translate_f 16/261
22/04/2020 Indy em Profundidade
3 SSL do servidor
.................................................. .................................................. ............................... 127
4 Convertendo certificados
..................................................
para o formato PEM .................................................. ............................... 127
Exportando o certificado
.................................................. .................................................. .................................................. .... 127
Converter .pfx em .pem
..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... .... ..... ..... ..... ..... ...... .... 12 7
Dividindo o arquivo .pem
..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... ..... .... ..... ..... ..... ..... ...... .... 12 8
Key.pem .................................................. .................................................. .................................................. .... 128
Cert.pem .................................................. .................................................. .................................................. .... 128
Root.pem .................................................. .................................................. .................................................. .... 128
Reconstrução de..................................................
2 núcleos .................................................. ............................... 133
Reestruturação do IOHandler
.................................................. .................................................. .................................................. .... 134
Interfaces de rede .................................................. .................................................. .................................................. .... 134
Fibras .................................................. .................................................. .................................................. .... 135
Agendadores .................................................. .................................................. .................................................. .... 135
Filas de trabalho .................................................. .................................................. .................................................. .... 137
Correntes .................................................. .................................................. .................................................. .... 137
Motores de corrente .................................................. .................................................. .................................................. .... 138
Page 11
Conteúdo VIII
https://translate.googleusercontent.com/translate_f 17/261
22/04/2020 Indy em Profundidade
Contextos .................................................. .................................................. .................................................. .... 138
https://translate.googleusercontent.com/translate_f 18/261
22/04/2020 Indy em Profundidade
Destruição determinística
.................................................. .................................................. ..................................... 148
Destruição não determinística
.................................................. .................................................. ..................................... 149
Coleta de lixo .................................................. .................................................. .................................................. ... 149
Etapas de portabilidade
.................................................. .................................................. .................................................. .... 149
Remover avisos....
não .....seguros
..... ..... ..... ..... ..... ..... ..... ...... .... ..... ..... ..... ..... ..... ..... ..... ..... ...... .... ..... ..... ..... .... ..... ..... ..... ..... ..... .. ... 14 9
Namespaces da ..................................................
unidade .................................................. .................................................. ... 149
Converter DFM.................................................. .................................................. .................................................. ... 150
Converter arquivo
.... .....
de projeto
..... ..... ..... ..... ..... ..... ..... ...... .... ..... ..... ..... ..... ..... ..... ..... ..... ...... .... ..... ..... ..... .... ..... ..... ..... ..... ..... .. ... 15 0
Resolver diferenças
..................................................
de classe .................................................. .................................................. ... 150
Adicionar sorte .................................................. .................................................. .................................................. ... 150
Créditos .................................................. .................................................. .................................................. .... 150
VIII
Page 12
IX Indy em Profundidade
Índice 153
https://translate.googleusercontent.com/translate_f 19/261
22/04/2020 Indy em Profundidade
https://translate.googleusercontent.com/translate_f 20/261
22/04/2020 Indy em Profundidade
Page 13
Seção
https://translate.googleusercontent.com/translate_f 21/261
22/04/2020 Indy em Profundidade
Introdução
Eu
Page 14
11 Indy em Profundidade
https://translate.googleusercontent.com/translate_f 22/261
22/04/2020 Indy em Profundidade
1 Introdução
Autores:
â € ¢ Chad Z. Hower, aka Kudzu - autor original do Indy e atual coordenador de projetos do Indy
â € ¢ Hadi Hariri - Co-Coordenador do Projeto Indy
Observe que esta é uma versão prévia! Existe uma grande quantidade de
material que está sendo trabalhado. Isso inclui consolidação,
atualização e importação de outras fontes. Além disso, você
veja vários tópicos que são preenchidos com notas e balbuciar. Isso é
onde estamos trabalhando e fornece uma visão do que é
chegando. Não se preocupe se algumas seções não fizerem sentido em
desta vez.
https://translate.googleusercontent.com/translate_f 23/261
22/04/2020 Indy em Profundidade
1.1.2 Atualizações
Atualizações do Indy in Depth podem ser encontradas em http://www.atozedsoftware.com/ .
1.1.3 Demonstrações
Todas as demos mencionadas neste livro estão disponíveis no Indy Demo Playground em
www.atozedsoftware.com .
Page 15
Introdução 12
1.2 Legal
https://translate.googleusercontent.com/translate_f 24/261
22/04/2020 Indy em Profundidade
https://translate.googleusercontent.com/translate_f 25/261
22/04/2020 Indy em Profundidade
Page 16
13 Indy em Profundidade
Todos os direitos reservados. Nenhuma parte deste trabalho pode ser reproduzida de nenhuma forma ou por qualquer meio - gráfico,
eletrônico ou mecânico, incluindo fotocópia, gravação, gravação ou armazenamento de informações e
sistemas de recuperação - sem a permissão por escrito do editor.
Os produtos mencionados neste documento podem ser marcas comerciais e / ou marcas comerciais registradas
dos respectivos proprietários. O editor e o autor não reivindicam essas marcas registradas.
Embora tenham sido tomadas todas as precauções na preparação deste documento, o editor e o
O autor não se responsabiliza por erros ou omissões ou por danos resultantes do uso de
informações contidas neste documento ou do uso de programas e código fonte que possam
acompanhá-lo. Em nenhum caso o editor e o autor serão responsáveis por qualquer perda de lucro ou qualquer
outros danos comerciais causados ou supostamente causados direta ou indiretamente por este
documento.
Se uma licença pessoal tiver sido comprada, este documento, seu conteúdo e todas as amostras associadas
O código é licenciado apenas para uso do indivíduo para o qual foi licenciado. Não pode ser compartilhado ou
distribuído a outros indivíduos.
Este documento não é transferível para outras pessoas, corporações ou entidades por método de venda, presente,
https://translate.googleusercontent.com/translate_f 26/261
22/04/2020 Indy em Profundidade
A corporação pode redistribuir este documento e o código-fonte associado se o acesso for restrito a
somente funcionários e contratados atuais da corporação.
Este documento não é transferível para outras pessoas, corporações ou entidades por método de venda, presente,
empréstimo ou outra transferência.
Page 17
Introdução 14
1.4 Créditos
Graças às seguintes pessoas, grupos, empresas:
â € ¢ A Indy Pit Crew e a Mercury Team por suas longas horas e dedicaçà £ o à Indy.
â € ” Para nà £ o, muitos outros que ajudaram Indy que nos esquecemos.
â € ¢ ECSoftware para produzir Ajuda e Manual com os quais este documento à © produzido e escrito.
http://www.helpandmanual.com
https://translate.googleusercontent.com/translate_f 28/261
22/04/2020 Indy em Profundidade
Page 18
https://translate.googleusercontent.com/translate_f 29/261
22/04/2020 Indy em Profundidade
Seção
II
Suporte técnico
https://translate.googleusercontent.com/translate_f 30/261
22/04/2020 Indy em Profundidade
Page 19
Suporte técnico 16
2 Suporte técnico
2.1 Nota
NÃO envie um email diretamente aos membros da Indy Pit Crew, a menos que seja especificamente solicitado
fazer isso (normalmente quando um membro da tripulação precisar de informações adicionais) ou responder a um e-mail de
um membro da Indy Pit Crew.
Devido à quantidade de tempo que os membros da Equipe Indy Pit passam nos grupos de notícias enquanto
ganhando seu pão diário, não conseguem responder a perguntas técnicas por e-mail. Técnico
as perguntas são melhor direcionadas ao grupo de notícias apropriado.
Se você precisar de respostas rápidas e prioritárias além do que fornecemos livremente, fora do nosso tempo livre e do nosso
livre-arbítrio, sem compensação financeira, consulte as opções de suporte pago abaixo. Mesmo com
suporte pago, já que o próprio Indy é totalmente gratuito, ainda é uma opção barata.
Se você ainda não está convencido por que não deve nos enviar e-mails diretamente, considere o seguinte
itens adicionais:
â € ¢ Indy à © feito por uma equipe. Isso significa que certas pessoas são responsáveis por certas partes do código.
Ao enviar um e-mail, você provavelmente o enviou à pessoa errada que não é a pessoa que conhece o
responde rapido.
â € ¢ O email alcança uma pessoa e, portanto, coloca a carga completamente nela. Usando as opções
abaixo, a equipe completa do Indy Pit, assim como muitos outros usuários do Indy, verão sua pergunta e os
pessoa apropriada será capaz de responder. Além disso, é provável que você receba uma variedade de respostas
de pessoas diferentes para ajudá-lo.
â € ¢ Leia tambà © m como fazer perguntas da maneira inteligente
https://translate.googleusercontent.com/translate_f 31/261
22/04/2020 Indy em Profundidade
â € ¢ borland.public.delphi.internet.winsock
â € ¢ borland.public.cppbuilder.internet.socket
â € ¢ borland.public.kylix.internet.sockets
Todos esses grupos de notícias existem em newsgroups.borland.com . Se você não puder acessá-los via NNTP, você
pode usar seu webrower para usar a interface da web em http://newsgroups.borland.com . Team Indy
monitora esses grupos regularmente e todos se beneficiam com sua postagem.
Page 20
17 Indy em Profundidade
https://translate.googleusercontent.com/translate_f 32/261
22/04/2020 Indy em Profundidade
2.6 Winsock 2
O Indy 9.0 requer o Winsock 2.0. Windows 98, Windows NT e Windows 2000 incluem o Winsock 2.0 por
padrão. Quando Indy é inicializado, ele verifica a versão do Winsock.
Windows 95 é o único sistema operacional que não oferece suporte ao Winsock 2.0 por padrão. no entanto
pode ser atualizado para o Winsock 2.0 baixando uma pequena atualização da Microsoft. O URL para este
o download é:
http://www.microsoft.com/windows95/downloads/contents/wuadmintools/s_wunetworkingtools/w95soc
kets2 /
O patch deve ser aplicado em qualquer caso, porque o Winsock que acompanha o Windows 95 contém
vários erros graves e vazamentos de memória que esse patch também corrige. O Windows 95 atualmente representa
menos de 5% dos sistemas atuais instalados. Muito poucos deles estão conectados a uma rede ou ao
Internet, então isso provavelmente terá muito pouco impacto na implantação de seus aplicativos.
https://translate.googleusercontent.com/translate_f 33/261
22/04/2020 Indy em Profundidade
Page 21
https://translate.googleusercontent.com/translate_f 34/261
22/04/2020 Indy em Profundidade
Seção
III
Introdução aos soquetes
https://translate.googleusercontent.com/translate_f 35/261
22/04/2020 Indy em Profundidade
Page 22
19 Indy em Profundidade
Existem vários conceitos que devem ser introduzidos primeiro. Sempre que possível, os conceitos serão comparados
para um conceito do mundo real que você provavelmente conhece: um sistema telefônico.
3.2. TCP / IP
TCP / IP é a abreviação de Transmission Control Protocol e Internet Protocol .
TCP / IP pode significar muitas coisas. É frequentemente usado de forma muito genérica como uma palavra "pegar tudo". Na maioria dos casos, é
refere-se ao próprio protocolo de rede.
3.3. Cliente
Um cliente é um processo que inicia uma conexão. Normalmente, os clientes conversam com um servidor por vez. Se um
processo precisa conversar com vários servidores, ele cria vários clientes.
3.4. Servidor
https://translate.googleusercontent.com/translate_f 36/261
22/04/2020 Indy em Profundidade
Um servidor
de muitos é um simultaneamente.
clientes processo que responde
Cadaaconexão
solicitações recebidas.
do servidor paraUm servidornotípico
o cliente, lidaécom
entanto, umavárias solicitações
tomada separada.
Comparando-o a uma ligação telefônica, o servidor seria a pessoa (ou correio de voz, sistema interativo etc.) que
atende o telefone quando toca. Um servidor é normalmente configurado para poder lidar com várias entradas
telefonemas. É semelhante a como um call center pode lidar com muitas chamadas, tendo centenas de
operadores e rotear cada chamada recebida para um operador disponível.
3.5 Endereço de IP
Cada computador em uma rede TCP / IP possui um endereço exclusivo associado. Alguns computadores podem
tem mais de um endereço associado a eles. Um endereço IP é um número de 32 bits e geralmente é
representado em notação de ponto, por exemplo, 192.168.0.1. Cada seção representa um byte do endereço de 32 bits.
Um endereço IP é como um número de telefone. Porém, assim como um local (residência, empresa, etc.) pode
tiver um ou mais números de telefone, uma máquina individual pode ter mais de um endereço IP
atribuído a ele. Diz-se que as máquinas que possuem mais de um endereço IP possuem hospedagem múltipla.
Para conversar com alguém em um local específico, é iniciada uma tentativa de conexão (uma chamada é feita e o
o telefone do local discado) discando o número de telefone desse local. A festa no toque
O final do telefone pode decidir se deve ou não atender o telefone.
Page 23
3.6. Porta
https://translate.googleusercontent.com/translate_f 37/261
22/04/2020 Indy em Profundidade
Uma porta é um
determinado número
endereço IP.inteiro que identifica qual aplicativo ou serviço o cliente deseja entrar em contato em um
Uma porta é muito parecida com uma extensão de telefone. Marcar um número de telefone o levará a um local, mas com
TCP / IP, todo local também possui uma extensão. Não há extensão padrão, como em residências
portanto, além de um endereço IP, uma porta sempre deve ser especificada ao se conectar a um
servidor.
Quando um servidor de aplicativos está pronto para aceitar solicitações de entrada, ele começa a escutar em uma porta. Isto é
por que às vezes aplicativo ou protocolo é usado de forma intercambiável com a palavra porta. Quando um cliente
deseja conversar com um servidor, ele deve saber onde está o aplicativo (endereço IP / número de telefone) e qual
porta (extensão) em que o aplicativo está ouvindo (atendendo).
Normalmente, os aplicativos têm uma porta fixa, de modo que, independentemente da máquina em que executam, a porta é fixa
para esse tipo de aplicativo. Por exemplo, HTTP (Web) usa a porta 80 e FTP usa a porta 21. Quando você
deseja recuperar uma página da Web, você só precisa saber o local do computador que deseja recuperar
a partir de, como você sabe, o HTTP usa a porta 80.
Os números de porta abaixo de 1024 são reservados e só devem ser usados se você estiver falando ou implementando
um protocolo conhecido que possui essa porta reservada para seu uso. Protocolos mais populares usam porta reservada
números.
3.7 Protocolo
A palavra protocolo é derivada do protocólon grego. Um protocollon era uma folha de papel colada a um
volume do manuscrito, descrevendo seu conteúdo.
Em termos de TCP / IP, um protocolo é uma descrição de como algo funciona. Mas mais genericamente é
geralmente se referindo a uma das duas coisas:
1. O tipo de soquete.
2. Um protocolo de comando de nível superior.
Quando se refere a soquetes, o protocolo especifica que tipo de soquete é. Tipos comuns de soquetes
são TCP , UDP eSoquetes ICMP .
Ao se referir a um protocolo de nível superior, refere-se aos comandos e respostas usados para executar
a função desejada. Esses protocolos são descritos nas RFCs . Exemplos de tais protocolos são
HTTP, FTP e SMTP.
3.8 Soquete
https://translate.googleusercontent.com/translate_f 38/261
22/04/2020 Indy em Profundidade
Todas as referências a um soquete neste artigo são referências ao TCP / IP. Um soquete é a combinação de um
Endereço IP , número da porta e protocolo . Um soquete também é um canal de comunicação virtual entre
dois processos. Esses processos podem ser localmente (residindo no mesmo computador) ou remotamente.
Um soquete é como uma conexão telefônica que carrega uma conversa. Para ter uma conversa, você deve
primeiro faça a ligação e peça à outra parte que atenda; caso contrário, nenhuma conexão (soquete) será
estabelecido.
Page 24
21 Indy em Profundidade
Os nomes de host são usados para tornar mais fácil para nós humanos e para permitir que um computador altere seu IP
endereço sem fazer com que todos os seus clientes em potencial (chamadores) percam o controle.
Um nome de host é como o nome de uma pessoa ou o nome da empresa. Uma pessoa ou empresa pode mudar sua
número de telefone, mas ainda podemos entrar em contato com eles.
3.10 DNS
DNS é a abreviação de Domain Name Service.
https://translate.googleusercontent.com/translate_f 39/261
22/04/2020 Indy em Profundidade
DNS é o serviço que traduz nomes de host em endereços IP . Para estabelecer uma conexão, um
O endereço IP deve ser usado, para que o DNS seja usado para procurar o endereço IP primeiro.
Para fazer uma ligação, você deve discar usando o número de telefone. Você não pode discar usando o
nome. Se você não possui o número de telefone da pessoa ou ele foi alterado, consulte o
número de telefone de uma pessoa na lista telefônica ou ligue para a assistência no diretório. Assim, o DNS é o telefone
assistência de livros / diretórios para a Internet.
3.11 TCP
TCP é a abreviação de Transmission Control Protocol .
Às vezes, o TCP também é conhecido como protocolo de fluxo. O TCP / IP inclui muitos protocolos e muitos
maneiras de se comunicar. Os transportes mais comuns são TCP e UDP. TCP é uma conexão
protocolo - ou seja, você deve se conectar a um servidor antes de poder enviar dados. TCP garante entrega
e precisão dos dados enviados e recebidos na conexão. O TCP também garante que os dados serão
chegar na ordem em que foi enviado. A maioria das coisas que usam TCP / IP usam TCP para seu transporte.
As conexões TCP são como usar uma ligação para manter uma conversa.
3.12 UDP
UDP é a abreviação de User Datagram Protocol .
UDP é para datagramas e é sem conexão. O UDP permite que pacotes "leves" sejam enviados para um host
sem ter que primeiro se conectar a outro host. Não é garantido que os pacotes UDP cheguem ao seu
destino e pode não chegar na mesma ordem em que foram enviados. Ao enviar um pacote UDP, é
enviado em um bloco. Portanto, você não deve exceder o tamanho máximo de pacote especificado pelo seu TCP / IP.
pilha .
Devido a esses fatores, muitas pessoas assumem que o UDP é quase inútil. Este não é o caso. Muitos
protocolos de streaming, como RealAudio, usam UDP.
Nota: O termo "streaming" pode ser facilmente confundido com a conexão "stream", que é TCP. Quando
você vê esses termos, precisa determinar o contexto em que eles são usados para determinar seus
significado próprio.
https://translate.googleusercontent.com/translate_f 40/261
22/04/2020 Indy em Profundidade
Page 25
Como o UDP não tem confirmação de entrega, não é garantido que ele chegue. Se você enviar um UDP
pacote para outro host, você não tem como saber se ele realmente chegou ao seu destino. A pilha
não irá - e não poderá - determinar isso e, portanto, não fornecerá um erro se o pacote não atingir seu
destino. Se você precisar dessas informações, precisará enviar algum tipo de notificação de retorno de
o host remoto.
UDP é como enviar a alguém uma mensagem em um pager tradicional. Você sabe que enviou, mas não envia
saber se eles receberam. O pager pode não existir, pode estar fora da área de serviço, pode não estar ligado ou
pode não estar funcionando. Além disso, a rede do pager pode perder a página. A menos que a pessoa pagine
você volta, não sabe se sua mensagem foi entregue. Além disso, se você enviar várias páginas, é
possível que eles cheguem fora de ordem.
3.13 ICMP
ICMP é a abreviação de Internet Control Message Protocol .
O ICMP é um protocolo de controle e manutenção. Normalmente, você não precisará usar o ICMP. Normalmente, é
usado para se comunicar com roteadores e outros dispositivos de rede. O ICMP permite que os nós compartilhem o status IP
e informações de erro. O ICMP é usado paraPING ,TRACEROUTE e outros protocolos.
3.14.
https://translate.googleusercontent.com/translate_f 41/261
22/04/2020 Indy em Profundidade
HOSTS é um arquivo de texto que contém uma tabela de pesquisa de host local. Quando a pilha tenta resolver um host
nome para um endereço IP , ele primeiro procura no arquivo HOSTS. Se existir uma entrada correspondente, ela será usada.
Se uma entrada não existir, ela continuará usando o DNS .
O nome do host e o endereço IP podem ser separados por espaços ou pelo caractere de tabulação. Comentários também podem
ser inserido no arquivo precedendo a linha com um caractere #.
HOSTS podem ser usados para falsificar entradas ou substituir entradas DNS . O arquivo HOSTS é frequentemente usado em
computadores em uma LAN pequena que não possui servidor DNS. O arquivo HOSTS também é útil para substituir o host
Endereços IP para depuração. Você não precisa ler o arquivo HOSTS; a pilha vai cuidar disso
detalhes para você de maneira transparente sempre que a resolução de nomes for necessária.
3.15 SERVIÇOS
Um arquivo SERVICES é semelhante a um Arquivo HOSTS . Em vez de resolver nomes de host emEndereços IP ,
resolve nomes de serviço nos números de porta aos quais estão atribuídos.
A seguir, é um arquivo de serviços parcial. Você pode procurar no seu computador um arquivo completo ou
Page 26
23 Indy em Profundidade
obtenha o RFC 1700. O RFC 1700 contém números de porta atribuídos e reservados:
eco 7 / tcp
eco 7 / udp
https://translate.googleusercontent.com/translate_f 42/261
22/04/2020 Indy em Profundidade
descartar Coletor 9 / tcp null
descartar 9 / udp coletor nulo
systat 11 / tcp usuários #Usuários ativos
systat 11 / tcp usuários #Usuários ativos
dia 13 / tcp
dia 13 / udp
qotd Cotação 17 / tcp #Citação do dia
qotd 17 / udp quote #Citação do dia
chargen 19 / tcp fonte ttytst #Personagem
# generator
chargen 19 / fonte ttytst udp #Personagem
# generator
ftp-data 20 / tcp #FTP data
ftp 21 / tcp Controle #FTP
telnet 23 / tcp
smtp Correio de 25 / tcp # Correio Simples
# Protocolo de Transferência
Você não precisa ler o arquivo SERVIÇOS; a pilha também cuidará desses detalhes para você. o
O arquivo SERVICES é lido por determinadas chamadas de função na pilha; no entanto, a maioria dos programas não os chama
funções e, portanto, ignora seus valores. Por exemplo, muitos programas FTP assumem o padrão 21 sem
sempre usando a pilha para procurar a porta para a entrada 'ftp'.
Normalmente, você nunca deve modificar este arquivo. Alguns programas, no entanto, adicionam uma entrada a este arquivo e
realmente usá-lo. Você pode alterar essa entrada para informar esses programas para usar outra porta. Um desses
programa é o Interbase. A Interbase efetua a seguinte entrada:
Você pode alterar esta entrada para fazer o Interbase usar uma porta diferente. Embora não seja prática comum
faça isso, é uma boa prática. Deve-se considerar se você escrever aplicativos de soquete, especialmente
servidores. Também é recomendável que os clientes usem a pilha para procurar o valor em SERVIÇOS,
especialmente para protocolos não padrão. Se nenhuma entrada for encontrada, um padrão deve ser usado.
https://translate.googleusercontent.com/translate_f 43/261
22/04/2020 Indy em Profundidade
Se 127.0.0.1 for usado em um cliente, ele sempre volta e procura um servidor no mesmo computador que
o cliente.
Isso é útil para depuração. Também pode ser usado para entrar em contato com qualquer serviço em execução no seu computador. E se
você possui um servidor da Web local, em vez de precisar saber o endereço IP do computador ou ter cada
desenvolvedor alterá-lo em scripts de teste, você pode especificar 127.0.0.1.
Page 27
3.17 Ping
Ping é um protocolo que verifica se um host é acessível pelo computador local. Ping é geralmente usado
em uma capacidade de diagnóstico.
O pedido expirou.
O pedido expirou.
https://translate.googleusercontent.com/translate_f 44/261
22/04/2020 Indy em Profundidade
O pedido expirou.
O pedido expirou.
3.18 TraceRoute
Pacotes TCP / IP não viajam diretamente de um host para outro. Pacotes são roteados como um carro
viaja de uma casa para outra. Normalmente, o carro deve percorrer mais de uma estrada para alcançar sua
destino. Pacotes TCP / IP viajam da mesma maneira. Cada vez que um pacote altera "estradas" em um
"intercâmbio", ele viaja através de um nó. Obtendo uma lista de nós ou "trocas" que um pacote
deve viajar entre os hosts, você pode determinar seu caminho. Isso é bastante útil para determinar por que
um host não pode ser alcançado.
O traceroute existe como um utilitário de linha de comando. O Traceroute exibe uma lista de roteadores IP (nós) que são
usado na entrega de um pacote do seu computador para o host especificado e por quanto tempo cada viagem (salto)
tomou. Esses horários podem ser úteis para determinar gargalos. O traceroute também pode exibir o último
roteador que manipulou com êxito seu pacote no caso de falha na transferência. Traceroute é usado para
diagnosticar ainda mais problemas detectados com o ping.
Rastreio concluído.
Page 28
25 Indy em Profundidade
3.19 LAN
LAN é a abreviação de Local Area Network .
O que define uma LAN é um termo difuso e pode variar dependendo de cada configuração de rede. Contudo
uma LAN normalmente se refere a todos os sistemas conectados por Ethernet (ou, em alguns casos, Token ring ou outro),
hubs e comutadores. A LAN não inclui outras LANs conectadas usando pontes ou
roteadores. Portanto, a LAN consiste apenas em lugares que o tráfego de rede pode alcançar sem precisar ser
passado para outra rede por uma ponte ou roteador.
Pense em uma LAN como as ruas de superfície de uma cidade, com pontes e roteadores sendo as estradas que
conectar cidades.
3,20 WAN
WAN é a abreviação de Wide Area Network .
Uma WAN se refere coletivamente a muitas LANs conectadas usando pontes e roteadores para formar uma rede maior.
rede.
Usando o exemplo da cidade novamente, uma WAN consistiria em muitas cidades (LANs) conectadas por
rodovias e interestaduais. A própria Internet também é classificada como uma WAN.
3.21 IETF
A IETF (Internet Engineering Task Force) é uma comunidade aberta que promove a operação,
estabilidade e evolução da Internet. O IETF funciona como o desenvolvimento de software de código aberto
equipes. O IETF pode ser encontrado em http://www.ietf.org/ .
3,22 RFC
https://translate.googleusercontent.com/translate_f 46/261
22/04/2020 Indy em Profundidade
Os RFCs são os documentos oficiais da IETF que descrevem e detalham os protocolos da Internet. RFC's
são identificados por números como RFC 822.
Existem muitos espelhos que contêm documentos RFC na Internet. Uma boa que permite
a pesquisa está disponível em:
http://www.rfc-editor.org/
3.23 Tópico
Um encadeamento é um caminho de execução de um programa. Muitos programas possuem apenas um thread. No entanto, outros
threads podem ser criados para criar caminhos de execução esperados.
Page 29
Em sistemas com várias CPUs, os threads podem ser distribuídos entre diferentes CPUs para acelerar
execução.
Em sistemas com apenas uma CPU, vários encadeamentos ainda podem ser executados usando preempção.
https://translate.googleusercontent.com/translate_f 47/261
22/04/2020 Indy em Profundidade
A preempção
Portanto, multitarefa
os threads a CPU no processamento
são virtualmente de muitos
executados como encadeamentos,
se houvesse dandoexecutando
CPU individual a cada umacada
uma thread
pequena fatia de tempo.
em paralelo.
3.24 Fork
O Unix, até recentemente, não suportava threading. Em vez de enfiar, o Unix usava bifurcação. Com rosqueamento,
uma linha de execução separada é estabelecida, mas existe no mesmo processo que outros threads e
compartilha assim o mesmo espaço de memória. A bifurcação faz com que o próprio processo seja "dividido". Um novo processo é
iniciado e os identificadores passados para ele.
A bifurcação não é tão eficiente quanto a rosqueamento, mas tem algumas vantagens. A bifurcação é mais estável.
A bifurcação também é mais fácil de programar em muitos casos.
A bifurcação é muito comum no Unix, pois o kernel o usa e suporta, enquanto o threading é bastante novo.
3,25 Winsock
Winsock é a abreviação de Windows Sockets .
O Winsock é uma API padrão definida e documentada para a programação de protocolos de rede. A maioria
geralmente é usado para programar TCP / IP, mas também pode ser usado para programar Novell (IPX / SPX) e outros
protocolos de rede. O Winsock está acessível como uma DLL que faz parte do Win32.
3,26 Pilha
O termo pilha refere-se à camada do sistema operacional que implementa a rede e
fornece a API para os desenvolvedores acessarem a rede.
https://translate.googleusercontent.com/translate_f 48/261
22/04/2020 Indy em Profundidade
Page 30
https://translate.googleusercontent.com/translate_f 49/261
22/04/2020 Indy em Profundidade
Seção
IV
Introdução ao Indy
https://translate.googleusercontent.com/translate_f 50/261
22/04/2020 Indy em Profundidade
Page 31
4 Introdução ao Indy
Normalmente, os servidores Unix possuem um ou mais processos de ouvinte que procuram solicitações de entrada de clientes.
Para cada cliente que ele precisa atender, ele bifurcará um novo processo para lidar com cada cliente. Isso faz
programação muito fácil, pois cada processo lida com apenas um cliente. O processo também é executado por conta própria
contexto de segurança, que pode ser definido pelo ouvinte ou pelo processo com base em credenciais, autenticação,
ou outros meios.
Os servidores Indy funcionam de maneira muito semelhante. O Windows, ao contrário do Unix, não se bifurca bem, mas encadeia
bem. Os servidores Indy alocam um encadeamento para cada conexão do cliente.
Quase todos os outros componentes usam chamadas sem bloqueio e agem de forma assíncrona. Eles exigem que você
responda a eventos, configure máquinas de estado e frequentemente execute loops de espera.
https://translate.googleusercontent.com/translate_f 51/261
22/04/2020 Indy em Profundidade
Por exemplo, com outros componentes, quando você chama connect, deve aguardar a ativação de um evento connect,
ou faça um loop até que uma propriedade indique que você está conectado. Com Indy, você simplesmente liga para o Connect e espera
para que retorne. Se for bem-sucedido, ele retornará quando concluir sua tarefa. Se falhar, aumentará um
exceção.
Trabalhar com Indy é muito parecido com trabalhar com arquivos. Indy permite que você coloque todo o seu código em um
local, em vez de espalhados por diferentes eventos. Além disso, a maioria acha que Indy é muito mais fácil
usar. O Indy também foi projetado para funcionar bem comtópicos . Se a qualquer momento você tiver problemas para implementar
algo com Indy, dê um passo atrás e aproxime-o como um arquivo.
Page 32
29 Indy em Profundidade
https://translate.googleusercontent.com/translate_f 52/261
22/04/2020 Indy em Profundidade
4.6 Rosqueamento
Threading é o processo de usar threads para implementar a funcionalidade. Indy usa threads extensivamente em
suas implementações e encadeamento de servidores também são úteis para os clientes.
Os soquetes sem bloqueio também podem ser rosqueados, mas requerem um manuseio extra e sua
as vantagens são perdidas com os soquetes de bloqueio.
https://translate.googleusercontent.com/translate_f 53/261
22/04/2020 Indy em Profundidade
Page 33
https://translate.googleusercontent.com/translate_f 54/261
22/04/2020 Indy em Profundidade
Seção
V
Bloqueio vs sem bloqueio
https://translate.googleusercontent.com/translate_f 55/261
22/04/2020 Indy em Profundidade
Page 34
31 Indy em Profundidade
Além disso, esses modelos não são multiplataforma e são implementados de maneira diferente e para diferentes
graus entre diferentes sistemas operacionais.
5.3 Bloqueio
Indy usa chamadas de soquete de bloqueio. O bloqueio de chamadas é como ler e gravar em um arquivo. Quando você
ler dados ou gravar dados, a função não retornará até que a operação esteja concluída. A diferença
trabalhar com arquivos versus soquetes é que as operações podem demorar muito mais porque os dados podem não
esteja imediatamente pronto para ler ou escrever. Uma operação de leitura ou gravação pode operar apenas tão rápido quanto o
rede ou o modem pode receber ou transmitir dados.
https://translate.googleusercontent.com/translate_f 56/261
22/04/2020 Indy em Profundidade
Com o Indy, para conectar um soquete, basta chamar o método Connect e aguardar o retorno. Se o
O método de conexão for bem-sucedido; ele retornará quando se conectar. Se o método Connect falhar, aumentará o
exceção apropriada.
Por exemplo, ao tentar conectar um soquete, você deve chamar o método Connect. The Connect
O método retornará imediatamente, antes que o soquete seja conectado. Quando o soquete está conectado, um
evento ocorrerá. Isso requer que a lógica da comunicação seja dividida em muitos procedimentos, ou a
uso de loops de votação.
Page 35
Havia o Windows e, eventualmente, alguém decidiu que seria uma boa ideia ter o
capacidade de programar TCP / IP no Windows. Portanto, eles portaram a popular API de soquete Unix. Isso permitiu
grande parte do código Unix existente é portado para o Windows facilmente.
https://translate.googleusercontent.com/translate_f 57/261
22/04/2020 Indy em Profundidade
Quando a API do soquete Unix foi portada para o Windows, ela foi chamada de Winsock .Winsock é a abreviação de
"Soquetes do Windows". Durante o porto, um problema surgiu rapidamente. No Unix, era comum bifurcar-se . Bifurcação
é semelhante ao multiencadeamento , mas com processos separados em vez de encadeamentos. Clientes e servidores Unix
processos de garfo para cada soquete. Esses processos são executados independentemente e usam o bloqueio
tomadas.
O Windows 3.1 não pôde se bifurcar efetivamente porque faltava multitarefa preemptiva e outras
Apoio, suporte. O Windows 3.1 também não tinha suporte paratópicos . O uso de soquetes de bloqueio causou ao usuário
interfaces para congelar. Como o Windows 3.1 usava multitarefa cooperativa, isso também causava
programas no sistema também não respondam. Como isso era altamente indesejável, não
extensões de bloqueio foram adicionadas ao WinSock para permitir que o Windows 3.x com suas falhas usassem
Winsock sem congelar todo o sistema. Essas extensões, no entanto, exigiram uma radicalmente diferente
maneira de programar soquetes. A Microsoft e outros consideraram que é do seu interesse difamar o bloqueio
soquetes em vez de destacar as deficiências do Windows 3.1.
Algumas extensões foram adicionadas para soquetes sem bloqueio no Unix. Essas extensões, no entanto, funcionam
bastante diferente das extensões não-bloqueantes no Windows. As extensões não são padrão
entre todas as plataformas Unix, e não em amplo uso. Soquetes de bloqueio no Unix ainda são usados em quase todos os
instância, e esse uso continuará sendo.
Soquetes de bloqueio também oferecem outras vantagens. Soquetes de bloqueio são muito melhores para rosquear ,
segurança e outros aspectos.
3. Trabalhar bem em threads - Como o uso de soquetes de bloqueio é de natureza seqüencial, eles são
inerentemente encapsulado e, portanto, bem adequado para uso em threads .
4. Não dependa de mensagens -Soquetes sem bloqueio dependem da mensagem da janela
sistema. Quando usado em threads, filas de mensagens separadas devem ser criadas. Quando não usado em
encadeamentos , situações de gargalo ocorrem facilmente quando várias conexões são tratadas.
Page 36
33 Indy em Profundidade
1. Interface do usuário "Freeze" com clientes - o bloqueio de chamadas de soquete não retorna até que eles tenham
cumpriram sua tarefa. Quando essas chamadas são feitas no thread principal de um aplicativo, o
O aplicativo não pode processar as mensagens da interface do usuário. Isso faz com que a interface do usuário
"congelar". O congelamento é causado porque a atualização, a repintura e outras mensagens não podem ser
processado até que as chamadas do soquete de bloqueio retornem o controle ao manipulador de mensagens dos aplicativos.
5,9 TIdAntiFreeze
Indy tem um componente especial que resolve o problema de congelamento da interface do usuário de forma transparente. o
existência de uma única instância TIdAntiFreeze em um aplicativo, permite o uso de bloqueio de chamadas no
thread principal sem que a interface do usuário esteja congelada. O TIdAntiFreeze é abordado com mais profundidade posteriormente.
https://translate.googleusercontent.com/translate_f 59/261
22/04/2020 Indy em Profundidade
1. Mais difícil de programar -O não bloqueio requer o uso de pesquisas ou eventos. Eventos são os
método mais comum, já que os laços de votação são bastante ineficientes. O uso de eventos requer que o
código do usuário ser dividido em muitos procedimentos, portanto, o rastreamento de estado foi adicionado. Isso leva ao código quebradiço que
é propenso a erros e difícil de modificar.
5.12 Comparação
Se você estiver familiarizado com o Indy e suas metodologias, poderá pular adiante. Se você tiver, no entanto
soquetes programados antes de usar o Indy, esta seção será útil para você.
Para quem nunca programou soquetes antes do Indy, é muito natural e fácil de usar. Mas pelo
para aqueles que já programaram tomadas antes, Indy normalmente apresenta um obstáculo inicial. Isto é
porque Indy funciona de maneira diferente. Isso não significa que outras abordagens estejam erradas, é apenas que Indy
é diferente. Tentar programar o Indy da mesma maneira que outras bibliotecas de soquetes é como tentar cozinhar
no microondas da mesma maneira que você cozinha no fogão. Os resultados serão desastrosos e talvez
até explosivo.
Se você já usou outras bibliotecas de soquetes, siga este conselho simples e sutil:
https://translate.googleusercontent.com/translate_f 60/261
22/04/2020 Indy em Profundidade
Page 37
Esquecer oque
você sabe!
Isso é muito mais fácil dizer do que fazer, no entanto, à medida que velhos hábitos morrem com dificuldade. Para enfatizar a diferença
comparação resumida será apresentada usando um exemplo. Para abstrair os conceitos e desconectar
seus padrões de pensamento dos soquetes, os arquivos serão usados. Este documento assume que você sabe
como ler e gravar em arquivos. (Ou seja, nenhum programador do Visual Basic está lendo isso
documento).
5.14 Cenário
Um cenário simples será apresentado que simplesmente gravará dados em um arquivo. Embora o procedimento para fazer isso
é bastante simples, aqui está detalhado para fins de demonstração:
1. Abra o arquivo
2. Escreva os dados
3. Feche o arquivo
https://translate.googleusercontent.com/translate_f 61/261
22/04/2020 Indy em Profundidade
Page 38
35 Indy em Profundidade
https://translate.googleusercontent.com/translate_f 62/261
22/04/2020 Indy em Profundidade
s: = 'Indy governa o mundo (Kudzu)!' + # 13 # 10 ;
tentar
// abre o arquivo
com TFileStream.Create ( 'c: \ temp \ test.dat' , fmCreate) tente
// Grava dados no arquivo
WriteBuffer (s [ 1 ], Comprimento (s));
// fecha o arquivo
finalmente livre; fim ;
fim ;
fim ;
Como você pode ver, ele corresponde um a um para as etapas descritas anteriormente e marcadas pelo
comentários. O código é seqüencial e prontamente entendido.
https://translate.googleusercontent.com/translate_f 63/261
22/04/2020 Indy em Profundidade
Tire um tempo para tentar entender o que está acontecendo. Se você usou soquetes sem bloqueio, você
entenderá esse código rapidamente. Uma descrição a seguir:
1. Button1Click é chamado e abre o arquivo. Enquanto o método Open retorna imediatamente, o arquivo é
ainda não está aberto e não pode ser acessado ainda.
2. O evento OnOpen é acionado quando o arquivo é aberto e está pronto para ser acessado. A
Page 39
É feita uma tentativa de gravação no arquivo, mas todos os dados podem não ser aceitos. O método Write será
retornar quantos bytes foram aceitos. O restante dos dados é salvo e será tentado novamente mais tarde.
3. O evento OnWrite é acionado quando o arquivo está pronto para que mais dados sejam gravados e a gravação
O método é tentado novamente com os dados restantes.
4. A etapa 3 é repetida continuamente até que todos os dados sejam aceitos pelo método Write. Quando todos
dados foram aceitos, o método Close é chamado. O arquivo ainda não está fechado.
5. O evento OnClose é disparado. O arquivo agora está fechado.
Para o exemplo sem bloqueio, basta abrir, gravar dados e fechar o arquivo necessário:
â € ¢ 3 eventos File1
â € ¢ 1 variável de membro do formulário
A versão sem bloqueio é mais complexa e difícil de entender. Dada a escolha entre estes
dois, muito se houver
escolha a maneira sem bloqueio. A maioria dos programadores de C ++ é excetuada, pois muitos deles são simplesmente
https://translate.googleusercontent.com/translate_f 64/261
22/04/2020 Indy em Profundidade
masoquistas
componentesefuncionam
também não escolheria,
usando porque
o modelo ambos são fáceis demais. No entanto, quase todas as tomadas
não-bloqueador.
Como você pode ver, o Indy é realmente muito parecido com o trabalho com arquivos. O Connect substitui o Open e
o Disconnect substitui o Close. Se você pensa e trata soquetes como ler e gravar em um arquivo, você
vai achar que usar o Indy é bem fácil.
https://translate.googleusercontent.com/translate_f 65/261
22/04/2020 Indy em Profundidade
Page 40
Seção
https://translate.googleusercontent.com/translate_f
VI 66/261
22/04/2020 Indy em Profundidade
Page 41
https://translate.googleusercontent.com/translate_f 67/261
22/04/2020 Indy em Profundidade
Anfitrião: = 'test.atozedsoftware.com' ;
Porta: = 6000 ;
Conectar; Tentar
// Leia e grave dados aqui
finalmente desconecte; fim ;
fim ;
O host e a porta também podem ser definidos no tempo de design usando o inspetor de objetos. Este é o código mínimo
necessário para escrever um cliente usando Indy. Os requisitos mínimos para criar um cliente são os seguintes:
Não há eventos OnError, portanto, não procure por eles. Isso pode parecer estranho se você tiver
usou outras bibliotecas de soquete, mas considere TFileStream. TFileStream não possui um evento OnError, ele
simplesmente gera exceções se houver um problema. Indy funciona exatamente da mesma maneira.
Assim como todos os arquivos abertos devem corresponder a um arquivo fechado, todas as chamadas do Connect no Indy devem corresponder
com uma chamada para Desconectar. Os clientes Indy básicos devem começar desta maneira:
Client.Connect; tentar
// Execute a leitura / gravação aqui
finalmente Client.Disconnect; fim ;
As exceções de Indy são fáceis de diferenciar de outras exceções de VCL, pois todas as exceções de Indy descem
de EIdException. Se você deseja manipular os erros do Indy separadamente dos erros do VCL, isso pode ser feito como em
o exemplo a seguir.
Nota: Para usar EIdException, você precisará adicionar IdException à sua cláusula usos.
tentar
Client.Connect; tentar
// Execute a leitura / gravação aqui
https://translate.googleusercontent.com/translate_f 68/261
22/04/2020 Indy em Profundidade
finalmente Client.Disconnect; fim ;
exceto
em E: EIdException começa
ShowMessage ( 'Exceção de Comunicação:' + E. Mensagem );
fim mais começar
ShowMessage ( 'Exceção VCL:' + E. Mensagem );
fim ;
Page 42
fim ;
Se houver um erro durante a chamada para o método Connect, ele se limpará antes de lançar o
exceção apropriada. Por esse motivo, a tentativa ocorre após a chamada para o Connect e não antes. No entanto, se
há uma exceção durante a transferência de dados, apenas uma exceção será gerada. O soquete permanecerá
conectado. É de sua responsabilidade tentar novamente sua operação ou desconectar. Na forma acima, nenhum extra
o manuseio é realizado e o soquete é desconectado após qualquer erro e após a conclusão normal.
Para também manipular erros durante a conexão e separá-los de outros erros de comunicação, seu
código deve estar no formato:
tentar
IdTCPClient1.Connect; tentar
tentar
// Faça suas comunicações aqui
finalmente IdTCPClient1.Disconnect; fim ;
exceto
em E: EIdException começa
ShowMessage ( 'Ocorreu um erro de rede durante a comunicação:'
+ E. Mensagem );
fim ;
em E: Exceção começa
ShowMessage ( 'Ocorreu um erro desconhecido durante a comunicação:'
+ E. Mensagem );
fim ;
fim ;
https://translate.googleusercontent.com/translate_f 69/261
22/04/2020 Indy em Profundidade
exceto
em E: EIdException começa
ShowMessage ( 'Ocorreu um erro de rede ao tentar conectar-se:'
+ E. Mensagem );
fim ;
em E: Exceção começa
ShowMessage ( 'Ocorreu um erro desconhecido ao tentar conectar:'
+ E. Mensagem );
fim ;
fim ;
Esse código não apenas verifica exceções que ocorrem durante a conexão, mas também separa tais
exceções de exceções que podem ocorrer durante as comunicações. Além disso, separa Indy
exceções de exceções não Indy.
Uma exceção é apenas algo fora do comum. Em termos de software, exceções são
algo que ocorre e altera o fluxo normal do programa.
Exceções são usadas para implementar erros no Delphi e, portanto, a maioria das exceções são erros. Contudo
existem exceções, como o EAbort, que não são erros. Indy também define várias exceções que
não são erros. Essas exceções geralmente descendem de EIdSilentException e, portanto, podem ser facilmente
distinto de erros e outras exceções.
6.4 TIdAntiFreeze
Indy tem um componente especial que resolve o problema de congelamento da interface do usuário de forma transparente. o
existência de uma única instância TIdAntiFreeze em um aplicativo, permite o uso de bloqueio de chamadas no
Page 43
https://translate.googleusercontent.com/translate_f 70/261
22/04/2020 Indy em Profundidade
O TIdAntiFreeze funciona temporizando internamente as chamadas para a pilha e permitindo que as mensagens sejam
processado durante os períodos de tempo limite. As chamadas externas para Indy continuam bloqueadas e, portanto, codificam
funciona exatamente como sem um TIdAntiFreeze.
Como o congelamento da interface do usuário é afetado apenas pelo bloqueio de chamadas no thread principal, o TIdAntiFreeze
afeta apenas as chamadas Indy feitas a partir do thread principal. Se um aplicativo usa Indy em threads,
TIdAntiFreeze não é necessário. Se usado, afetará apenas as chamadas feitas a partir do encadeamento principal.
O uso de um TIdAntiFreeze diminui um pouco a comunicação do soquete. Quanta prioridade deve ser
dada à aplicação versus a comunicação do soquete é configurável com as propriedades de
TIdAntiFreeze. A razão pela qual o uso de um TIdAntiFreeze diminui a comunicação do soquete é que o
o thread principal tem permissão para processar mensagens. Devido a esse cuidado, deve-se tomar cuidado para não permitir
muito tempo a ser consumido em eventos causados por mensagens. Isso inclui a maioria dos eventos da interface do usuário
como OnClick, OnPaint, OnResize e muitos outros. Como soquetes sem bloqueio dependem de mensagens
o problema descrito sempre se aplica a soquetes sem bloqueio. Com Indy e o
Para uso opcional de um TIdAntiFreeze, o programador tem controle total.
O objetivo da pesquisa de código postal é fornecer a cidade e o estado de um determinado código postal (CEP
código para leitores americanos). Os dados de amostra incluídos no servidor contêm dados para correios dos EUA
códigos. Os códigos postais dos EUA (chamados CEP) têm 5 dígitos e são numéricos.
https://translate.googleusercontent.com/translate_f 71/261
22/04/2020 Indy em Profundidade
O servidor responde com uma saudação quando o cliente se conecta. Saudações e respostas aos comandos
normalmente contêm um número de 3 dígitos, especificando o status. Isso será abordado mais detalhadamente mais tarde
Page 44
Seções.
Após a saudação, o servidor está pronto para aceitar comandos do cliente. Se um comando de pesquisa for
recebido, o servidor responderá com uma lista de códigos postais seguidos pelo local associado. o
resposta é encerrada por a. em uma linha por si só. O cliente pode emitir quantos comandos quiser
até que o cliente especifique que está pronto para desconectar emitindo o comando Quit.
https://translate.googleusercontent.com/translate_f 72/261
22/04/2020 Indy em Profundidade
O cliente de código postal consiste em dois botões, uma caixa de listagem e uma nota. Um botão é usado para limpar
resultados, e o outro é usado para obter valores do memorando e solicitar informações do servidor.
Os resultados são exibidos na caixa de listagem.
Em um aplicativo normal, o usuário teria opções para especificar o host, a porta e possivelmente até o proxy
informações de configuração. No entanto, para fins de demonstração, o host foi definido como planejado
tempo para 127.0.0.1 (Auto) e a porta para 6000.
Os métodos Indy usados aqui serão explicados apenas brevemente, pois são abordados com mais detalhes em outros
Seções.
O código começa desativando o botão para que o usuário não possa tentar realizar outra pesquisa enquanto
um está em andamento. Você pode pensar que isso não é possível porque os eventos de clique no botão são processados
usando mensagens. No entanto, esta demonstração possui um TIdAntiFreeze que chama Application.ProcessMessages
e permite que eventos de pintura e outros eventos de clique ocorram. Por esse motivo, você precisa tomar mais
cuidado para proteger o estado das ações do usuário.
https://translate.googleusercontent.com/translate_f 73/261
22/04/2020 Indy em Profundidade
resposta
respondaécom
204.um
Se código
o servidor responder
diferente com um
se estiver código
muito diferente,
ocupado, uma exceçãoetc.
em manutenção será gerada. Um servidor pode
Para cada código postal digitado pelo usuário, a demonstração envia um comando de pesquisa ao servidor e
espera uma resposta de 200, seguida por uma resposta. SendCmd envia o comando e chama GetResponse
Page 45
passando o segundo parâmetro (neste caso 200). Se o SendCmd for bem-sucedido, a demonstração chamará Capture
que lê uma resposta até a. é encontrado em uma linha por si só. Como a demo está enviando apenas uma
código postal por comando, espera apenas uma linha para uma resposta ou nenhuma se o código postal for inválido.
Finalmente, a demonstração envia o comando Quit, aguarda uma resposta 201 que reconhece que o servidor
concorda e desconecta. É sempre uma boa ideia usar um comando Quit para que ambos os lados conheçam um
a desconexão está prestes a ocorrer.
https://translate.googleusercontent.com/translate_f 74/261
22/04/2020 Indy em Profundidade
Page 46
https://translate.googleusercontent.com/translate_f 75/261
22/04/2020 Indy em Profundidade
Seção
VII
https://translate.googleusercontent.com/translate_f 76/261
22/04/2020 Indy em Profundidade
UDP
Page 47
UDP 44
7 UDP
https://translate.googleusercontent.com/translate_f 77/261
22/04/2020 Indy em Profundidade
Nota: O termo "streaming" pode ser facilmente confundido com a conexão "stream", que é TCP. Quando
você vê esses termos, precisa determinar o contexto em que eles são usados para determinar seus
significado próprio.
7.2 Confiabilidade
A confiabilidade dos pacotes UDP depende da confiabilidade e da saturação da rede. UDP
pacotes são frequentemente usados em aplicativos executados em uma LAN, pois a LAN é muito confiável. Pacotes UDP
na Internet também são geralmente confiáveis e podem ser usadas com correção de erros ou com mais frequência
interpolação. Interpolação é quando um palpite é feito sobre a falta de dados com base em pacotes
recebido antes e / ou depois. A entrega, no entanto, não pode ser garantida em nenhuma rede - portanto, não
assuma que seus dados sempre chegarão ao seu destino.
Como o UDP não tem confirmação de entrega, não é garantido que ele chegue. Se você enviar um UDP
pacote para outro host, você não tem como saber se ele realmente chegou ao seu destino. A pilha
não irá - e não poderá - determinar isso e, portanto, não fornecerá um erro se o pacote não atingir seu
destino. Se você precisar dessas informações, precisará enviar algum tipo de notificação de retorno de
o host remoto.
UDP é como enviar a alguém uma mensagem em um pager tradicional. Você sabe que enviou, mas não envia
saber se eles receberam. O pager pode não existir, pode estar fora da área de serviço, pode não estar ligado ou
pode não estar funcionando. Além disso, a rede do pager pode perder a página. A menos que a pessoa pagine
você volta, não sabe se sua mensagem foi entregue. Além disso, se você enviar várias páginas, é
possível que eles cheguem fora de ordem.
Outro exemplo do mundo real que é semelhante ao UDP, é o serviço postal. Você pode enviá-lo, mas você
não pode garantir que será entregue ao destino. Pode ser perdido em qualquer lugar ao longo do caminho, ou
entregue, mas mutilado antes do parto.
7.3 Transmissões
O UDP possui uma capacidade única, geralmente o recurso que o torna desejável. Essa capacidade é a capacidade de
ser transmitido. A transmissão significa que uma única mensagem pode ser enviada, mas pode ser recebida por
muitos destinatários. Isso não é o mesmo que multicasting. Multicasting é um modelo de assinatura em que
os destinatários se inscrevem e são adicionados a uma lista de distribuição. Com a transmissão, uma mensagem é enviada
https://translate.googleusercontent.com/translate_f 78/261
22/04/2020 Indy em Profundidade
Page 48
45 Indy em Profundidade
e receba. O usuário não precisa notificar a estação de rádio que deseja ouvir.
Um IP de broadcast específico pode ser calculado com base no IP do remetente e em uma máscara de sub-rede. Contudo
na maioria dos casos, é mais fácil usar 255.255.255.255, que será transmitido o mais longe possível.
Quase todos os roteadores, no entanto, estão programados para filtrar as mensagens de broadcast por padrão. Isso significa
mensagens não passarão por pontes ou rotas externas, e a transmissão será limitada ao
rede local LAN.
Por esse motivo, é recomendável que os pacotes UDP sejam mantidos em 8192 bytes ou menos, se você estiver
transmitindo além da LAN local. Em muitos casos, mesmo esse valor pode ser muito grande. Ser estar
absolutamente certo, mantenha todos os pacotes UDP de 1024 bytes ou menos.
7,5 Confirmações
Em um ambiente de LAN, o UDP é bastante confiável. No entanto, quando a WAN ou a Internet estão envolvidas, você pode
deseja implementar uma variedade de esquemas de confirmação.
7.5.2 Agradecimentos
No sistema de reconhecimento, cada pacote é reconhecido pelo receptor como tendo sido
recebido. Se nenhuma confirmação for recebida dentro de um determinado período após a transmissão, é
retransmitido.
Como os reconhecimentos podem ser perdidos, cada pacote deve ter um único
identificador. Normalmente esse identificador é simplesmente um número de sequência. Isso é para que o destinatário possa filtrar
pacotes duplicados, se os receber, e também para que as mensagens de reconhecimento possam identificar o
pacote que eles estão confirmando o recebimento.
7.5.3 Sequenciamento
Pacotes podem ser identificados com um número de sequência. Este número pode ser usado pelo destinatário para
determinar se estão faltando pacotes. Em seguida, ele pode solicitar novamente que os pacotes ausentes específicos sejam reenviados ou, em alguns casos,
Em casos como o áudio, ele pode interpolar dados dos pacotes vizinhos e adivinhar melhor o
pacote ausente ou simplesmente ignore o pacote perdido.
Esse comportamento de pacotes ausentes pode ser ouvido com áudio real ou com um celular (celular) digital quando
pacotes são perdidos. Em alguns sistemas, você apenas ouve pular ou lacunas. Noutros casos em que o
Como os pacotes são pequenos e o sistema interpola, você pode ouvir um som de "worble".
Page 49
https://translate.googleusercontent.com/translate_f 80/261
22/04/2020 Indy em Profundidade
UDP 46.
7.6 TIdUDPClient
TIdUDPClient é o cliente UDP base para enviar pacotes UDP para outros destinos. A maioria
O método mais usado é o Send, que usa as propriedades Host e Port para enviar um pacote UDP. isto
aceita uma string como argumento.
Há também um método SendBuffer que executa a mesma tarefa que Send, exceto que ele aceita um
Buffer e tamanho como argumentos.
O TIdUDPClient também pode ser usado como um servidor para aguardar e receber pacotes UDP de entrada em um
base individual.
7,7 TIdUDPServer
Como o UDP não possui conexão, o TIdUDPServer opera de maneira diferente do TIdTCPServer. TIdUDPServer
não possui modos semelhantes ao TIdSimpleServer, mas como o UDP não possui conexão, o TIdUDPClient
possui métodos de escuta de uso único.
O TIdUDPServer quando ativo cria um encadeamento de escuta para escutar pacotes UDP de entrada. Para cada
Pacote UDP recebido, o TIdUDPServer disparará o evento OnUDPRead no thread principal ou no diretório
contexto do segmento de escuta, dependendo do valor da propriedade ThreadedEvent.
Quando ThreadedEvent for false, o evento OnUDPRead será disparado no contexto do programa principal
fio. Quando ThreadedEvent for true, o evento OnUDPRead é acionado no contexto do ouvinte
fio.
Quando ThreadedEvent for verdadeiro ou falso, sua execução bloqueará o recebimento de mais mensagens.
Por isso, o processamento do evento OnUDPRead deve ser rápido.
https://translate.googleusercontent.com/translate_f 81/261
22/04/2020 Indy em Profundidade
O exemplo é chamado invocador remoto de BSOD - ou RBSOD, para abreviar. RBSOD pode ser usado para disparar
BSODs falsos em máquinas de colegas (ou inimigos). Os BSODs acionados não são reais e
não fará com que a pessoa perca nenhum dado. No entanto, eles devem dar-lhes um susto. O BSOD pode
também ser limpo remotamente.
O RBSOD consiste em dois programas. O servidor que deve ser executado na máquina remota e o
cliente que é usado para controlar e acionar os BSODs.
Muitas opções são fornecidas. Dependendo das opções selecionadas, o BSOD pode ser feito para
parece bastante autêntico, ou pode ser feito para parecer uma piada. No entanto, quando eles são feitos para
aparecer como uma piada, o usuário levará alguns segundos para entender isso e fornecer a ele uma
de sobressalto.
Page 50
47 Indy em Profundidade
https://translate.googleusercontent.com/translate_f 82/261
22/04/2020 Indy em Profundidade
Endereço de IP
Especifica o endereço IP ou o nome do host do computador que você deseja acionar o
BSOD. O servidor deve estar instalado e em execução no computador remoto.
Se esse campo for deixado vazio, a mensagem será transmitida pela sub-rede local (em
na maioria dos casos, a LAN local) e todos os computadores com o servidor instalado e
executando exibirá o BSOD.
mensagem
Mensagem é a mensagem de erro que será exibida ao usuário na tela BSOD. O padrão
mensagem é:
Uma exceção fatal OE ocorreu em 0028: C0011E36 no VXD VMM (01) 00010E36. o
o aplicativo atual será encerrado.
Este texto foi retirado de um BSOD real e parecerá bastante real para o usuário.
Muitos haicais japoneses (uma forma especial de um poema japonês) também estão incluídos por diversão. tem
muitos muito engraçados para escolher. Aqui estão dois dos meus favoritos:
O Windows travou novamente. Eu sou a tela azul da morte. Ninguém ouve seus gritos.
Três coisas são certas: morte, impostos e perda de dados. Adivinha o que ocorreu.
https://translate.googleusercontent.com/translate_f 83/261
22/04/2020 Indy em Profundidade
Imagine o rosto dos seus colegas depois que eles perceberem que foram enganados. Tenha muito cuidado
quando você executa essa brincadeira em chefes do tipo Dilbert ou programadores do Visual Basic, no entanto. Eles podem
Page 51
UDP 48.
Essas mensagens estão contidas em messages.dat e você pode adicionar as suas também.
Essa opção mantém os programadores do Visual Basic e os chefes do Dilbert ocupados por horas procurando por
a tecla Qualquer. Essa opção é melhor utilizada imediatamente antes de sair para o aeroporto em uma longa viagem de negócios ou
quando você precisar mantê-los ocupados por um tempo.
https://translate.googleusercontent.com/translate_f 84/261
22/04/2020 Indy em Profundidade
* O BSOD é uma marca comercial da Microsoft Corporation.
mostrar
O botão show acionará o BSOD nos computadores remotos.
Claro
Clear pode ser usado para limpar remotamente os BSODs acionados. Normalmente você deixará o usuário final limpo
próprio BSOD, mas em alguns casos você pode limpá-lo remotamente.
7.8.2 Servidor
Vamos dar uma olhada no servidor primeiro.
Instalação
O servidor é nomeado svchost em vez de RBSODServer ou outro nome sensível. Isto é para que
você pode instalá-lo facilmente em outros computadores enquanto o oculta. svchost é um executável normal do Windows
que normalmente várias cópias estão em execução. Se você procurar no gerenciador de tarefas agora, provavelmente verá
quatro entradas para este executável. Como você colocará esta versão especial em seu próprio diretório, ela não será
interferir com o windows, mas parecerá o mesmo normal quando visualizado no gerenciador de tarefas.
O servidor não possui janelas e não aparecerá na bandeja do sistema ou na bandeja de tarefas. Se você quiser
para pará-lo, use o gerenciador de tarefas e selecione o svchost que está sendo executado como o usuário conectado. o
svchosts do sistema estará sendo executado como SYSTEM. Depois de selecionar sua versão, você pode usar
FINALIZAR TAREFA.
Para a maioria das instalações, basta copiar a versão compilada do servidor no computador de destino (compilar
sem pacotes para uma implantação mais fácil) e execute-o. Ele permanecerá na memória até o usuário reiniciar sua
computador. Depois que eles reiniciarem, o programa não será recarregado. Se você deseja que o programa automaticamente
Para recarregar, você pode adicioná-lo ao grupo de inicialização dos usuários ou usar entradas do Registro para uma inicialização mais furtiva.
Page 52
https://translate.googleusercontent.com/translate_f 85/261
22/04/2020 Indy em Profundidade
Código fonte
O servidor consiste em duas unidades, Server.pas e BSOD.pas. O BSOD.pas contém um formulário usado
para exibir a tela BSOD. O BSOD.pas não contém nenhum código Indy e, portanto, não será coberto
aqui.
Server.pas é o principal formulário de inscrição e contém um único servidor UDP. A propriedade port foi
definido como 6001 e a propriedade ativa foi definida como True. Quando o aplicativo é executado, ele
comece imediatamente a escutar na porta 6001 os pacotes UDP recebidos.
Como discutido anteriormente, o UDP é semelhante a um pager. Por esse motivo, não são necessárias conexões
para receber dados. Pacotes de dados simplesmente chegam como uma peça. Para cada pacote UDP recebido, o
O servidor UDP dispara o evento OnUDPRead. Nenhum outro evento é necessário para implementar um servidor UDP.
Quando o evento OnUDPRead é acionado, o pacote completo será recebido e agora será
disponível para uso.
https://translate.googleusercontent.com/translate_f 86/261
22/04/2020 Indy em Profundidade
fim;
fim;
Observe que existe uma instrução if que verifica se o tamanho é 0. É legal enviar e receber
pacotes UDP vazios. Nesse caso, é usado para sinalizar ao servidor para limpar o BSOD.
Se o tamanho não for 0, os dados serão lidos em uma sequência local usando TStream.ReadBuffer.
O servidor UDP não usa um thread individual para cada pacote; portanto, ocorrem eventos OnUDPRead
sequencialmente. Por padrão, o OnUDPRead é acionado no thread principal para que formulários e outros controles da GUI possam
seja acessado com segurança.
7.8.3 Cliente
O cliente RBSOD é ainda mais simples que o servidor. O cliente RBSOD consiste em um formulário: Main.pas.
O Main.pas contém vários eventos, mas a maioria deles está relacionada à interface do usuário e deve ser
Page 53
UDP 50.
auto-explicativo.
IdUDPClient1.Host: = editHost.Text;
IdUDPClient1.Send (
iif (chckShowAnyKey.Checked, 'T', 'F')
+ iif (chckTrademark.Checked, 'T', 'F')
+ s);
A primeira linha define o host para o qual o pacote UDP será enviado. A porta já foi definida em
o tempo de design usando o inspetor de propriedades e corresponde ao do servidor com o valor 6001.
https://translate.googleusercontent.com/translate_f 87/261
22/04/2020 Indy em Profundidade
A próxima linha usa o método Send para enviar o pacote UDP. Como o UDP é sem conexão, qualquer dado
deve ser enviado como vários pacotes ou empacotado em um único pacote. Se vários pacotes forem enviados,
é responsabilidade dos desenvolvedores coordená-los e remontá-los. Esta não é uma tarefa tão trivial quanto
aparecer, portanto, a menos que você esteja enviando grandes quantidades de dados, é muito mais fácil reunir os dados em
um único pacote.
O argumento passado para enviar será enviado imediatamente como um pacote UDP e, portanto, quando for chamado, todos os
os dados que você deseja enviar devem ser passados em uma única chamada.
Indy também contém um método SendBuffer sobrecarregado para enviar dados usando buffers.
No caso do RBSOD, o protocolo consiste simplesmente em dois caracteres que especificam opções para mostrar o
marca comercial e mostre qualquer tecla, seguida da mensagem real a ser exibida.
O único outro código Indy no cliente RBSOD está no botão OnClick for Clear e é quase
idêntico ao trecho anterior.
https://translate.googleusercontent.com/translate_f 88/261
22/04/2020 Indy em Profundidade
Page 54
Seção
https://translate.googleusercontent.com/translate_f 89/261
22/04/2020 Indy em Profundidade
Leitura e escrita
VIII
Page 55
Leitura e escrita 52
https://translate.googleusercontent.com/translate_f 90/261
22/04/2020 Indy em Profundidade
8 Leitura e escrita
O Indy suporta muitos métodos de leitura e gravação de dados para atender a muitas necessidades diferentes. Estes
Os métodos incluem métodos para aguardar, verificar status e pesquisa.
Cada um desses métodos pertence à classe TIdTCPConnection. Este é o tipo de cada servidor
conexão e um ancestral de TIdTCPClient. Isso significa que você pode usar todos esses métodos em
servidores e clientes.
A maioria das pessoas conhece apenas alguns dos métodos de leitura e gravação. Além disso, muitas pessoas
Nunca use os clientes principais, mas apenas os clientes de protocolo e, portanto, pode não estar familiarizado com nenhum dos clientes principais.
métodos.
Lembre-se, o Indy está bloqueando, portanto, não procure eventos para notificá-lo quando a operação solicitada for
completo. Os métodos não retornam até que a tarefa solicitada seja concluída. Se a tarefa solicitada não puder
for concluída, uma exceção ocorrerá.
Este não é um conjunto completo de documentação para cada método. Para isso, você deve consultar o arquivo de ajuda do Indy.
Esta seção foi projetada apenas para familiarizá-lo com os métodos.
https://translate.googleusercontent.com/translate_f 91/261
22/04/2020 Indy em Profundidade
Page 56
53 Indy em Profundidade
8.1.1 AllData
função AllData: string;
AllData bloqueia e coleta os dados recebidos até a conexão ser desconectada. Em seguida, retorna
os dados coletados como resultado. AllData é útil para protocolos como WhoIs que, após uma entrada fornecida
retornar dados e sinalizar o final dos dados desconectando. AllData armazena em buffer os dados na memória, portanto
não pode ser usado com grandes quantidades de dados.
8.1.2 Captura
procedimento Capture (ADest: TStream; const ADelim: string = '.';
const AIsRFCMessage: Boolean = True); sobrecarga;
https://translate.googleusercontent.com/translate_f 92/261
22/04/2020 Indy em Profundidade
A captura possui vários formulários sobrecarregados. Em resumo, o Capture lerá os dados até o especificado
delimitador é encontrado em uma linha por si só.
8.1.3 CurrentReadBuffer
função CurrentReadBuffer: string;
CurrentReadBuffer retorna todos os dados atualmente contidos no buffer de recebimento interno da Indy. Antes
retornando dados, o CurrentReadBuffer também tentará ler todos e quaisquer dados que também estejam aguardando
o soquete, se conectado. Chamar CurrentReadBuffer esvazia o buffer interno.
8.1.4 InputBuffer
propriedade InputBuffer: TIdManagedBuffer lê FInputBuffer;
InputBuffer é uma referência a uma instância de um objeto TIdManagedBuffer. InputBuffer é interno da Indy
receber buffer. O TIdManagedBuffer possui vários métodos avançados, mas geralmente os usuários não
precisa chamar isso.
8.1.5 InputLn
função InputLn (const AMask: String = ''; AEcho: Boolean = True; ATabWidth: Inteiro
= 8; AMaxLineLength: Inteiro = -1): String;
https://translate.googleusercontent.com/translate_f 93/261
22/04/2020 Indy em Profundidade
caracteres que são lidos. InputLn é útil ao obter dados que você não deseja exibir para o
Page 57
Leitura e escrita 54
8.1.6 ReadBuffer
O ReadBuffer é usado para ler dados diretamente em um buffer de memória especificado. O ReadBuffer lerá os dados
do soquete, se não houver dados suficientes disponíveis no buffer interno da Indy.
8.1.7 ReadCardinal
função ReadCardinal (const AConvert: boolean = true): Cardinal;
8.1.8 ReadFromStack
função ReadFromStack (const ARaiseExceptionIfDisconnected: Boolean = True;
ATimeout: Inteiro = IdTimeoutDefault;
ReadFromStack é usado para preencher o buffer de recebimento interno da Indy. Normalmente, os usuários finais nunca devem chamar isso
a menos que estejam implementando um novo método de leitura que não use outra leitura existente
https://translate.googleusercontent.com/translate_f 94/261
22/04/2020 Indy em Profundidade
métodos, ou eles estão interagindo diretamente com o buffer de recebimento interno usando o InternalBuffer
propriedade.
8.1.9 ReadInteger
função ReadInteger (const AConvert: boolean = true): Inteiro;
O ReadInteger lê um número inteiro de 32 bits assinado na conexão, ajustando opcionalmente o byte da rede
ordem.
8.1.10 ReadLn
função ReadLn (ATerminator: string = LF; const ATimeout: Integer =
IdTimeoutDefault; AMaxLineLength: Inteiro = -1): string; virtual;
ReadLn lê os dados da conexão até que o terminador seja encontrado, o tempo limite se esgote ou
o comprimento máximo da linha é atingido.
8.1.11 ReadLnWait
função ReadLnWait (AFailCount: Integer = MaxInt): string;
ReadLnWait funciona como ReadLn, com a exceção de que ele não retornará até que uma linha não \ vazia
encontrado. Também retornará se as linhas vazias do AFailCount forem lidas.
Page 58
55 Indy em Profundidade
https://translate.googleusercontent.com/translate_f 95/261
22/04/2020 Indy em Profundidade
8.1.12 ReadSmallInt
função ReadSmallInt (const AConvert: Boolean = true): SmallInt;
ReadSmallInt lê um número inteiro pequeno da conexão, ajustando opcionalmente a ordem dos bytes da rede.
8.1.13 ReadStream
procedimento ReadStream (AStream: TStream; AByteCount: LongInt = -1; const
AReadUntilDisconnect: boolean = false);
O ReadStream lê dados em um fluxo. Uma contagem de bytes específica pode ser especificada, lida a partir do fluxo,
ou o fluxo pode ser lido até desconectar.
8.1.14 ReadString
função ReadString (const ABytes: Inteiro): string;
ReadString lê o número especificado de bytes em uma string e retorna os dados como resultado.
8.1.15 ReadStrings
procedimento ReadStrings (var AValue: TStrings; AReadLinesCount: Integer = -1);
ReadStrings lê um número especificado de seqüências terminadas por EOLs a partir da conexão. Se uma string
count não é especificado, um número inteiro de 32 bits é lido pela primeira vez na conexão e esse número é usado.
8.1.16 WaitFor
função WaitFor (const AString: string): string;
O tempo limite não é um tempo limite para uma unidade de trabalho completa. É um tempo limite inativo. Ou seja, se a quantidade de
passar o tempo especificado na propriedade ReadTimeout e nenhuma parte dos dados puder ser gravada, um
A exceção EIdReadTimeout será gerada.
Muitas vezes uma conexão de rede fica muito lenta ou não transfere dados, mas permanece conectada e
válido. Em tais situações, a conexão pode se tornar tão lenta que se torna inutilizável e apenas
torna-se um fardo para o servidor e inútil para o cliente.
Page 59
Para lidar com essas situações, Indy implementa tempos limite de leitura usando a propriedade ReadTimeout de
TIdTCPConnection. O padrão ReadTimeout é 0, o que desativa o tempo limite da leitura. Para habilitar uma leitura
timeout especifique um valor em milissegundos.
Durante qualquer chamada de leitura, se o tempo limite de leitura especificado e nenhum dado for recebido da conexão, um
A exceção EIdReadTimeout será gerada. O tempo limite não se aplica aos dados solicitados.
recebido com no período de tempo limite, mas com quaisquer dados. Se você solicitar 100 bytes de dados a serem lidos e um
tempo limite de leitura de 1000 milissegundos (1 segundo) a operação de leitura ainda pode demorar mais de 1 segundo.
Somente se 1 segundo passar sem que um único byte seja recebido, a exceção EIdReadTimeout será
cresça.
https://translate.googleusercontent.com/translate_f 97/261
22/04/2020 Indy em Profundidade
https://translate.googleusercontent.com/translate_f 98/261
22/04/2020 Indy em Profundidade
Page 60
57 Indy em Profundidade
8.3.1 SendCmd
função SendCmd (const AOut: string; const AResponse: SmallInt = -1): SmallInt;
sobrecarga;
função SendCmd (const AOut: string; const AResponse: matriz de SmallInt): SmallInt;
sobrecarga;
SendCmd é usado para enviar um comando de texto e analisar uma resposta numérica no estilo RFC.
8.3.2 Gravação
procedure Write (AOut: string);
A gravação é o método de saída mais básico do Indy. Write envia o parâmetro AOut para a conexão.
A gravação não altera o parâmetro AOut de forma alguma.
8.3.3 WriteBuffer
procedimento WriteBuffer (const ABuffer; AByteCount: Longint; const AWriteNow: Boolean =
Falso);
WriteBuffer permite que um buffer de memória direto seja gravado. Se AWriteNow for especificado, o buffer de gravação será
ser ignorado se estiver em uso no momento.
https://translate.googleusercontent.com/translate_f 99/261
22/04/2020 Indy em Profundidade
8.3.4 WriteCardinal
procedimento WriteCardinal (AValue: Cardinal; const AConvert: Boolean = True);
WriteCardinal grava um cardeal de 32 bits não assinado na conexão, ajustando opcionalmente a rede
ordem de bytes.
8.3.5 WriteHeader
procedimento WriteHeader (AHeader: TStrings);
WriteHeader grava um objeto TStrings na conexão, convertendo a sequência '=' para uma ':' para cada
item. O WriteHeader também grava uma linha em branco após gravar o objeto TStrings.
8.3.6 WriteInteger
procedimento WriteInteger (AValue: Inteiro; const AConvert: Boolean = True);
WriteInteger grava um número inteiro de 32 bits assinado na conexão, ajustando opcionalmente o byte da rede
ordem.
Page 61
https://translate.googleusercontent.com/translate_f 100/261
22/04/2020 Indy em Profundidade
8.3.7 WriteLn
procedimento WriteLn (const AOut: string = '');
WriteLn executa a mesma função que Write, com a exceção de que ele também grava um EOL (CR + LF)
após o parâmetro AOut.
8.3.8 WriteRFCReply
procedimento WriteRFCReply (AReply: TIdRFCReply);
WriteRFCReply grava uma resposta numérica + de estilo RFC de texto usando o objeto TIdRFCReply especificado.
8.3.9 WriteRFCStrings
procedimento WriteRFCStrings (AStrings: TStrings);
8.3.10 WriteSmallInt
procedimento WriteSmallInt (AValue: SmallInt; const AConvert: Boolean = True);
WriteSmallInt grava um pequeno número inteiro na conexão, ajustando opcionalmente a ordem dos bytes da rede.
8.3.11 WriteStream
procedimento WriteStream (AStream: TStream; const AAll: Boolean = True; const
AWriteByteCount: Boolean = False; const ASize: Inteiro = 0);
WriteStream grava um fluxo especificado na conexão. WriteStream contém muitos parâmetros para
especificando quais partes do fluxo são gravadas e, opcionalmente, pode gravar a contagem de bytes no
conexão também.
https://translate.googleusercontent.com/translate_f 101/261
22/04/2020 Indy em Profundidade
8.3.12 WriteStrings
procedimento WriteStrings (AValue: TStrings; const AWriteLinesCount: Boolean = False);
8.3.13 WriteFile
função WriteFile (AFile: String; const AEnableTransferFile: Boolean = False):
Cardeal;
WriteFile é uma função para gravar o conteúdo de um arquivo diretamente na conexão. Usos WriteFile
otimizações do sistema operacional para gravar o arquivo no soquete que produz melhor desempenho do que
Page 62
Enviar muitos pequenos pedaços de dados pode confundir o algoritmo ou fazer com que ele cause muitos
pacotes a serem enviados. Como cada pacote também possui sobrecarga, isso desperdiça largura de banda e diminui a velocidade
https://translate.googleusercontent.com/translate_f 102/261
22/04/2020 Indy em Profundidade
transferência de dados.
Os dados podem ser armazenados em buffer em uma string ou outra e enviados de uma só vez, no entanto, isso colocaria o requisito
no seu código e também provavelmente altere a maneira como você enviou dados, pois você não teria toda a gravação
métodos disponíveis durante o armazenamento em buffer. Isso também complicaria seu código e aumentaria o uso de memória.
Em vez disso, você pode usar o recurso de buffer de gravação da Indy. Ao usar o buffer de gravação, você está permitindo que o Indy
armazene dados de saída em buffer e permita que você use o Indy normalmente com todas as chamadas de gravação ativadas.
Para iniciar o buffer de gravação, chame OpenWriteBuffer e especifique um tamanho de buffer. Então você pode ligar para qualquer um dos
As funções de gravação do Indy e toda a saída são armazenadas em buffer até que o tamanho do buffer seja atingido. Cada vez que o buffer
atingido o tamanho, o buffer será gravado na conexão e limpo. Se nenhum tamanho de buffer for especificado,
todos os dados serão armazenados em buffer até serem liberados manualmente.
Para concluir o buffer de gravação, chame CancelWriteBuffer ou CloseWriteBuffer. CloseWriteBuffer grava qualquer
dados restantes e conclui o buffer de gravação, enquanto CancelWriteBuffer fecha o buffer sem
transmitindo o que ele contém.
As transações são predefinidas por vários métodos no Indy, como TIdHTTP.Get, WriteStream, etc.
Como usuário, você também pode definir suas próprias transações usando BeginWork, DoWork e EndWork .
Quando uma transação começa, um evento OnWorkBegin será acionado. O evento OnWorkBegin especifica
https://translate.googleusercontent.com/translate_f 103/261
22/04/2020 Indy em Profundidade
Page 63
Leitura e escrita 60
Em seguida, uma série de eventos do OnWork é acionada. O evento OnWork especifica Sender, WorkMode e
o WorkCount atual. Este evento é útil para atualizar as barras de progresso.
Para executar uma transação, primeiro chame BeginWork com o tamanho da transação, se conhecido. Então ligue
DoWork com atualizações sobre o andamento. Quando terminar, ligue para o EndWork.
https://translate.googleusercontent.com/translate_f 104/261
22/04/2020 Indy em Profundidade
Page 64
https://translate.googleusercontent.com/translate_f 105/261
22/04/2020 Indy em Profundidade
Seção
IX
Detectando desconexões
https://translate.googleusercontent.com/translate_f 106/261
22/04/2020 Indy em Profundidade
Page 65
Detectando desconexões 62
9 Detectando desconexões
Como o Indy está bloqueando a natureza e seus eventos são apenas relacionados ao status, não há nenhum evento para notificar sobre
uma conexão prematuramente desconectada. Se uma chamada de leitura ou gravação estiver em andamento, quando uma ocorrência prematura
Se a desconexão ocorrer, uma exceção será gerada e poderá ser detectada. Se nenhuma chamada de leitura ou gravação estiver em
progresso, nenhuma exceção será gerada até que uma chamada de leitura ou gravação seja tentada.
Nos protocolos baseados em comandos TCP, a maneira mais fácil é se despedir. Isso detectará apenas quando um
conexão adequada ocorreu, mas esta é uma grande ajuda.
Para se despedir, os protocolos usam o comando QUIT. Quando um cliente está pronto para desconectar, em vez de
apenas desconectando, ele emite primeiro um comando QUIT no servidor. Em seguida, aguarda uma resposta e
depois desconecta o soquete.
Suas boas maneiras e permite que ambos os lados se desconectem adequadamente. Não fazer isso é como falar em um
telefone e, inesperadamente, a outra pessoa desliga. Você não sabe o que aconteceu e fica
adivinhar até você decidir desligar também.
A diferença é que um servidor pode ter centenas ou milhares de clientes. Se todos eles se desconectarem
sem informar o servidor, o servidor terá várias conexões "inoperantes" para reconciliar.
Isso pode parecer estranho, mas é o mesmo que se estivéssemos acessando um arquivo. Imagine que você tem um
planilha do Excel aberta que existe em um disquete. Você está trabalhando no arquivo, mas ele é armazenado em cache
memória e excel não está lendo ou escrevendo no momento atual. Em algum momento desse período, você
esqueça que você tem a planilha aberta e remove o disquete da unidade. Mais tarde,
você volta a trabalhar na sua planilha. Tudo está bem até você salvar suas alterações. Somente então
você recebe um erro. O Excel não recebeu uma "EAnIdiotRemovedTheFloppyDiskException" quando você
removeu o disquete, mesmo que o Excel tivesse um arquivo aberto nesse disco.
https://translate.googleusercontent.com/translate_f 108/261
22/04/2020 Indy em Profundidade
(C) 2003 Atozed Computer Software Ltd.
Este livro está registrado para Jan West
Page 66
você detectar desconexões imediatamente é contrário à maneira como o TCP / IP foi projetado. Tal
detecção pode ser implementada, mas é importante que você entenda por que ela não funciona
dessa maneira por padrão. Sua compreensão disso o ajudará a implementar adequadamente
detecção de desconexão
Na maioria dos casos, se você pensar bem, verá que esse comportamento é aceitável e até desejável.
No entanto, há situações em que é muito importante saber se uma conexão foi perdida. Imagine
que você está implementando a interface entre um monitor cardíaco e um sistema de monitoramento de telemetria.
Este é um caso em que você definitivamente deseja saber se a conexão foi perdida e muito rapidamente.
Se você precisar de uma notificação imediata das desconexões, precisará implementar essa detecção no
protocolo.
Há uma vantagem adicional obtida com a implementação de um sistema keep-alive. Em muitos casos, um
A conexão TCP pode permanecer válida, no entanto, um dos processos para de responder e para
solicitações de manutenção. Em outros casos, o processo pode continuar atendendo solicitações, mas a uma taxa muito lenta
seja eficaz devido a problemas no serviço ou à degradação da largura de banda da rede. Guarda-
Oives detectará essa condição e a marcará como inadequada para uso, mesmo que a conexão ainda seja válida.
Keep-alives podem ser enviados em intervalos regulares, ou apenas nos momentos em que é necessário determinar o
https://translate.googleusercontent.com/translate_f 109/261
22/04/2020 Indy em Profundidade
9.3.2 Pings
Os pings são implementados de forma semelhante para manter vivos, com a exceção de que eles não são retornados em resposta
a uma solicitação. Os pings são enviados de um lado da conexão para o outro em intervalos regulares. 1
o lado se torna o radiodifusor e um lado se torna o monitor. Se uma quantidade de tempo especificada
decorrido no monitor desde que o último ping chegou sem que um novo chegasse, a conexão é
determinado como inadequado e rescindido.
Pings podem ser considerados um pulso ou um batimento cardíaco. Se parar ou diminuir, há um problema.
9,4 EIdConnClosedGracfully
Muitos usuários do Indy se incomodam com a exceção EIdConnClosedGraceful que é gerada com o Indy
servidores, especialmente o HTTP e outros servidores. EIdConnClosedGraceful é uma exceção de sinalização
que a conexão foi fechada pelo outro lado intencionalmente. Isto não é o mesmo que um quebrado
conexão que causaria um erro de redefinição de conexão. Se o outro lado fechar a conexão
e o soquete é lido ou gravado, EIdConnClosedGracfully será gerado por Indy. Isso é semelhante a
tentando ler ou gravar em um arquivo que foi fechado sem o seu conhecimento.
Em alguns casos, essa é uma exceção verdadeira e seu código precisa lidar com isso. Em outros casos (normalmente
servidores) esta é uma parte normal do funcionamento do protocolo e o Indy lida com essa exceção para
você. Mesmo que Indy o pegue, ao executar no IDE, o depurador será acionado primeiro. Você
Page 67
Detectando desconexões 64
basta pressionar F9 para continuar e Indy tratará da exceção, mas a parada constante durante
a depuração pode ser bastante irritante. Nos casos em que Indy capturar a exceção, seus usuários irão
https://translate.googleusercontent.com/translate_f 110/261
22/04/2020 Indy em Profundidade
nunca verá uma exceção no seu programa, a menos que seja executada a partir do IDE.
9.4.1 Introdução
https://translate.googleusercontent.com/translate_f 111/261
22/04/2020 Indy em Profundidade
Page 68
65 Indy em Profundidade
1. Acordo mútuo - Ambos os lados concordam em se desconectar mutuamente por um lado sinalizando (e o outro
opcionalmente reconhecendo) e, em seguida, ambos os lados se desconectam explicitamente.
2. Desconexão única - Desconecte e deixe o lado remoto notar.
Com o método do acordo mútuo, ambos os lados sabem quando desconectar e explicitamente
desconectar. A maioria dos protocolos de conversação, como correio, notícias etc., se desconecta dessa maneira. Quando
o cliente está pronto para desconectar, envia um comando ao servidor informando que será desconectado. o
O servidor responde com uma confirmação da solicitação de desconexão e, em seguida, o cliente e
desconexão do servidor. Nesses casos, um EIdConnClosedGracfully não deve ser gerado, e se um
ocorre de fato um erro e deve ser tratado.
Em alguns casos de desconexão mútua, nenhum comando será emitido, mas ambos os lados sabem quando o outro
irá desconectar. Geralmente, um cliente se conecta, emite um comando, recebe a resposta do servidor
https://translate.googleusercontent.com/translate_f 112/261
22/04/2020 Indy em Profundidade
e desconecte. Embora nenhum cliente explícito tenha sido emitido pelo cliente, o protocolo declara que o
a conexão deve ser desconectada após um comando e resposta. Alguns dos protocolos de tempo são
exemplos disso.
Com o Single Disconnect, um lado se desconecta. O outro lado é deixado para detectar isso e depois
ação apropriada para encerrar a sessão. Com protocolos que usam esse método de desconexão, você
verá EIdConnClosedGraceful e é normal. É uma exceção, mas Indy sabe disso e vai
lidar com isso para você. O protocolo whois é um exemplo disso. O cliente se conecta ao servidor e
envia uma string contendo o domínio para consulta. O servidor envia a resposta e desconecta
quando a resposta estiver concluída. Nenhum outro sinal é enviado ao cliente além de uma desconexão normal
que a resposta está concluída.
O HTTP permite o acordo mútuo e a desconexão única e é por isso que é comum
consulte o EIdConnClosedGraceful com o servidor HTTP. HTTP 1.0 funciona de maneira semelhante ao protocolo whois
em que o servidor sinaliza o cliente simplesmente desconectando após a solicitação ter sido atendida. o
O cliente deve usar novas conexões para cada solicitação.
O HTTP 1.1 permite que uma única conexão solicite vários documentos. No entanto, não há comando para
sinalizar uma desconexão. A qualquer momento, o cliente ou o servidor podem se desconectar após uma resposta. Quando
o cliente desconecta, mas o servidor ainda está aceitando solicitações, um EIdConnClosedGraceful será
levantada. Na maioria dos casos, no HTTP 1.1, é o cliente que desconecta. Um servidor desconectará
quando implementa parte do HTTP 1.1, mas não suporta a opção keep alive.
O EIdConnClosedGracfully é gerado a partir de uma rotina principal, no entanto, quando essa rotina é chamada, é
normalmente vários métodos chamam profundamente. O EIdConnClosedGracfully é de fato uma exceção e precisa
para ficar preso pelo chamador mais alto na maioria dos casos. A maneira correta de lidar com isso é uma exceção.
9.4.4 É um erro?
Todas as exceções não são erros. Muitos desenvolvedores foram ensinados ou assumiram que todas as exceções são
erros. No entanto, esse não é o caso, e é por isso que eles são chamados de exceções e não de erros.
https://translate.googleusercontent.com/translate_f 113/261
22/04/2020 Indy em Profundidade
Page 69
Exceções são exatamente isso - exceções. Delphi e C ++ Builder usam exceções para manipular erros em
uma maneira elegante. No entanto, as exceções têm outros usos além dos erros. EAbort é um exemplo
de uma exceção que não é necessariamente um erro. Exceções como essas são usadas para modificar padrões
programe o fluxo e comunique as informações a um nível de chamada mais alto, onde elas ficam presas. Indy usa
exceções de tal maneira também.
Nos servidores, é uma exceção. No entanto, às vezes é um erro, e às vezes é uma exceção. Para
Em muitos protocolos, essa exceção faz parte do funcionamento normal do protocolo. Por causa disso
comportamento comum, se você não pegar o EIdConnClosedGracfully no código do servidor, o Indy o fará. isto
marcará a conexão como fechada e interromperá o encadeamento atribuído à conexão. Se você deseja
você pode lidar com essa exceção, caso contrário a Indy a tratará e tomará as ações apropriadas
para você automaticamente.
https://translate.googleusercontent.com/translate_f 114/261
22/04/2020 Indy em Profundidade
Page 70
https://translate.googleusercontent.com/translate_f 115/261
22/04/2020 Indy em Profundidade
Seção
X
Protocolos de implementação
https://translate.googleusercontent.com/translate_f 116/261
22/04/2020 Indy em Profundidade
Page 71
Protocolos de implementação 68
10 Protocolos de implementação
Indy implementa todos os protocolos comuns e também muitos dos protocolos menos usados. tem
Ainda há casos em que você precisará implementar protocolos por conta própria. O motivo mais comum para
implementar um protocolo é que você precisa implementar algo personalizado para o qual não existe protocolo.
O primeiro passo é entender o protocolo que será implementado. Existem três tipos básicos de
protocolos:
1. Padrão - Estes são protocolos que são padrões da Internet. Para entender o protocolo simplesmente
encontre as RFCs associadas ao protocolo. As RFCs detalharão o protocolo em profundidade.
2. Personalizado - os protocolos personalizados são usados quando não existe um protocolo para a função desejada. Criando um
protocolo personalizado será abordado a seguir.
3. Fornecedor - refere-se a protocolos que fazem interface com sistemas ou dispositivos proprietários. Fornecedor
protocolos são protocolos que o fornecedor desenvolveu como um protocolo personalizado e agora você é deixado para
interface com. Desejo-lhe boa sorte nos protocolos de fornecedores, porque a maioria deles é
https://translate.googleusercontent.com/translate_f 117/261
22/04/2020 Indy em Profundidade
implementado por designers de hardware que tiveram uma aula de C ++ na faculdade e não têm experiência
na implementação de protocolos.
A maioria dos protocolos é de conversação e texto sem formatação e, a menos que você tenha um motivo convincente,
todos os seus protocolos também devem ser. Esses dois termos são abordados nas seções a seguir.
A primeira etapa na construção de um cliente ou servidor é entender o protocolo. Para protocolos padrão, esse
realizado lendo a RFC apropriada. Para protocolos personalizados, um protocolo deve ser estabelecido.
A maioria dos protocolos é de conversação e texto simples. Conversacional significa que um comando é dado, um
segue a resposta de status e possivelmente dados. Protocolos com escopo muito limitado geralmente não são
conversacional, mas ainda são geralmente texto sem formatação. O texto sem formatação facilita muito a depuração de protocolos e
interface para usar diferentes linguagens de programação e sistemas operacionais.
Os códigos de status são tradicionalmente um número de 3 dígitos. Não existe um padrão que defina códigos de status ou seus
convenções, mas muitos protocolos seguem uma convenção de fato do seguinte:
1xx - Informativo
2xx - Sucesso
Cada erro normalmente tem um número único associado a ele, mas alguns protocolos reutilizam números e
apenas forneça resposta numérica exclusiva para cada comando e não para o protocolo.
Page 72
69 Indy em Profundidade
O uso de texto sem formatação garante fácil depuração e teste. Também garante a interoperabilidade entre
sistemas operacionais e linguagens de programação.
10.1.2 Comando
Um comando é uma sequência de texto que é enviada entre um cliente e um servidor para solicitar informações ou que
alguma operação seja realizada. Exemplos de comandos são HELP, QUIT, LIST, etc.
Exemplo:
GET CHARTS.DAT
Os comandos são sempre codificados em inglês. Isso pode parecer tendencioso, porém um terreno comum deve
ser escolhido e o inglês é o idioma mais comum tanto no mundo técnico quanto no
mundo dos negócios. Se o inglês não for usado, os protocolos não serão muito úteis.
Um exemplo de localização de comandos está no Microsoft Office. O Microsoft Office pode ser automatizado
usando automação OLE. No entanto, a Microsoft localizou os nomes dos métodos e propriedades do
objetos. Isso significa que, se você escrever um aplicativo usando o Microsoft Office Automation para os EUA
https://translate.googleusercontent.com/translate_f 119/261
22/04/2020 Indy em Profundidade
versão, seu software não funcionará na França, onde os usuários provavelmente têm a versão francesa da Microsoft
Escritório.
10.1.3 Responder
Uma resposta é uma resposta curta enviada em resposta a um comando que foi emitido. A resposta
contém informações de status sobre o sucesso ou falha da capacidade de executar a solicitação
comando e, às vezes, também contém pequenas quantidades de dados.
Por exemplo, se o comando GET customer.dat for emitido, uma resposta de 200 OK poderá ser retornada
indicando que o comando foi entendido e será processado. As respostas são normalmente apenas uma linha,
mas pode conter várias linhas.
Ao contrário dos comandos, a parte textual das respostas pode ser localizada em outros idiomas, desde que
está em conformidade com ASCII de 7 bits. Isso ocorre porque o próprio protocolo depende da parte numérica e da
parte textual é para exibição ao usuário final ou depuração.
10.1.4 Resposta
Uma resposta é a parte de dados retornada em resposta a um comando. As respostas são opcionais
e não acompanhe todos os comandos. As respostas ocorrem depois que a resposta foi enviada para que o remetente
do comando sabe se deve esperar uma resposta ou não, e o formato da resposta.
Page 73
Protocolos de implementação 70
As respostas podem ser textuais ou binárias. Se uma resposta é textual, geralmente éFormato de resposta RFC .
10.1.5 Conversas
https://translate.googleusercontent.com/translate_f 120/261
22/04/2020 Indy em Profundidade
A maioria dos protocolos é conversacional. Alguns simples não são, mas geralmente ainda são texto simples .
Uma conversa significa que a estrutura de comando do protocolo é construída da seguinte maneira:
1. Comando dado
2. Resposta de status retornada
3. Resposta de dados opcional
Comando:
Resposta:
Servidor: 200 Ok
Resposta:
Uma exceção notável é o POP3. É um mistério o motivo pelo qual os designers decidiram não apenas ser diferentes
do que qualquer outro RFC. O protocolo POP3 é realmente mais limitado e não oferece outros
funcionalidade relacionada ao protocolo. Foi uma diversão completamente desnecessária.
https://translate.googleusercontent.com/translate_f 121/261
22/04/2020 Indy em Profundidade
O IMAP4, que pretendia ser o sucessor do POP3, promove essa tendência com mais incômodos e
mecanismos não padronizados. O IMAP4 não é amplamente utilizado e o POP3 continua sendo o correio padrão
protocolo.
Além dessas duas menções notáveis, os protocolos de texto seguem um "quase padrão" estabelecido.
Esse "quase padrão" é uma maneira uniforme de enviar comandos, respostas e respostas.
Page 74
71 Indy em Profundidade
Os três dígitos numéricos contêm o significado da resposta e são usados no tempo de execução para detectar o resultado
de um comando. Geralmente, o texto opcional a seguir é para exibição ao usuário ou para fins de depuração.
Nesses casos, a resposta é geralmente em inglês, mas pode ser localizada enquanto ASCII de 7 bits for usado. Em
alguns casos em que os dados são curtos, eles são retornados no campo de texto opcional. Nesses casos, os dados
ainda deve ser ASCII de 7 bits, mas o próprio protocolo determina as restrições de idioma e formatação. Em
na maioria dos casos, é neutro em dados e idioma. Um exemplo pode ser um comando "TIME" que retorna
"15:30" no campo de texto opcional.
https://translate.googleusercontent.com/translate_f 122/261
22/04/2020 Indy em Profundidade
404 é a resposta numérica e "Não existe arquivo" é a mensagem de texto opcional. Apenas 404 deve ser
interpretado neste caso pelo programa como 404 seria definido pelo protocolo para significar exatamente isso.
A mensagem de texto é apenas para depuração, registro ou exibição para o usuário. A mensagem de texto pode variar
de implementação em implementação e talvez localizado em outros idiomas. Idiomas que
não pode ser exibido corretamente em 7 bits, o ASCII deve ser transliterado para caracteres em inglês.
A parte numérica do código de status pode ser atribuída a qualquer significado. No entanto, é comum
convenção a seguir a seguinte regra:
1xx - Informativo
2xx - Sucesso
3xx - Erro temporário
4xx - Erro permanente
5xx - Erro interno
Os números são geralmente únicos, mas nem sempre. Ou seja, se você atribuir 201 para significar "Arquivo não encontrado",
muitos comandos podem responder com 201 e o significado é sempre o mesmo. Em alguns casos mais raros, o
O significado do número depende do comando emitido. Ou seja, cada comando atribui específica
significados para cada resposta numérica.
Os códigos numéricos que terminam em 00, ou seja, 100, 200 e assim por diante, são reservados para respostas gerais que
não tem significados específicos associados a eles. 200 é frequentemente associado simplesmente a "Ok".
Os códigos de status também podem ser multilinhas para conter respostas de texto maiores. Nesses casos, várias linhas são
enviado com cada linha, exceto a última contendo um traço após o código numérico, em vez de um espaço.
10.2.1.1 Exemplos
Aqui estão alguns exemplos de códigos de status retirados do protocolo HTTP. Como você pode ver, eles correspondem
à categorização pelo primeiro dígito.
https://translate.googleusercontent.com/translate_f 123/261
22/04/2020 Indy em Profundidade
Page 75
Protocolos de implementação 72
200 Ok
Redirecionamento 302
404 Página Não Encontrada
500 Erro interno
Se você viu 500 Internal Internal , é provável que você esteja usando o Microsoft IIS.
As respostas RFC são muito comuns quando a quantidade de dados a ser retornada é desconhecida. É usado por
HTTP, Correio, Notícias e outros protocolos.
Os métodos Indy que oferecem suporte à resposta RFC são Capture (para recebimento) e WriteStrings (para envio).
Exemplo de transação:
GET File.txt
201 segue o arquivo
Olá,
Para gerar uma resposta, configure a propriedade NumericCode (ou TextCode) e, opcionalmente, insira o texto no campo
Propriedade de texto. O texto é do tipo TStrings para permitir respostas em várias linhas.
O TIdRFCReply possui métodos para escrever respostas formatadas corretamente e também para analisar texto em um
Instância TIdRFCReply.
TIdRFCReply é usado para enviar respostas a comandos e também por ReplyException, ReplyUnknown
Propriedades de saudação do TIdTCPServer.
Page 76
73 Indy em Profundidade
10.4 Responder
O código numérico em uma resposta normalmente é exclusivo para cada erro. O protocolo HTTP, por exemplo, usa
404 para "Recurso não encontrado". Muitos comandos diferentes têm permissão para retornar 404 como um erro, mas
404 sempre significa o mesmo erro. Para evitar a duplicação do texto para o erro 404 sempre que
https://translate.googleusercontent.com/translate_f 125/261
22/04/2020 Indy em Profundidade
ReplyTexts é uma coleção de instâncias TIdRFCReply que podem ser gerenciadas em tempo de execução ou tempo de design.
ReplyTexts é usado para manter uma lista de textos que corresponde a cada código numérico. Quando um
TIdRFCReply é usado em um servidor TCPS que possui um código numérico, mas sem texto, o Indy procurará um
correspondência correspondente em ReplyTexts e use seu texto.
Portanto, em vez de precisar incluir o texto sempre que um 404 for necessário, como mostrado aqui:
ASender.Reply.NumericCode: = 404;
Antes de Indy realmente enviar a resposta, ela definirá a propriedade Text da resposta a partir de uma entrada correspondente em
ReplyTexts. Isso permite que todos os textos de resposta sejam mantidos em um local central e sejam gerenciados com facilidade.
A resposta é mais simples do que se poderia pensar inicialmente. O servidor é mais fácil de construir primeiro. Para testar um
cliente, você precisa de um servidor. Para testar um servidor, você precisa de um cliente. No entanto, uma vez que quase todos os protocolos são
Com base em texto, um cliente pode ser facilmente simulado usando um aplicativo telnet.
Para testar isso, conecte-se a um servidor conhecido em sua porta. Em um shell de comando, digite:
Agora pressione enter. Após a conexão, você deverá ver uma tela semelhante à da figura abaixo.
https://translate.googleusercontent.com/translate_f 126/261
22/04/2020 Indy em Profundidade
Page 77
Protocolos de implementação 74
https://translate.googleusercontent.com/translate_f 127/261
22/04/2020 Indy em Profundidade
Windows 95/98 / ME e NT podem parecer um pouco diferentes do Windows 2000 ou Windows XP, mas
os resultados são os mesmos. Outras versões do Windows iniciam o telnet como um novo aplicativo com seus próprios
janela. A figura acima é do cliente de telnet do Windows XP, que é um aplicativo de console.
A primeira etapa na construção de um cliente ou servidor é entender o protocolo. Para protocolos padrão, esse
realizado lendo a RFC apropriada. Se o protocolo não for um padrão ou já estiver definido, um
deve ser definido.
â € ¢ Comandos de texto ou binários? A menos que haja um requisito obrigatório, use comandos de texto. Texto
comandos são mais fáceis de entender e depurar.
â € ¢ TCP ou UDP? Isso realmente depende do protocolo que está sendo construído e das necessidades. Estude o
características de ambos e decidir com cuidado. Na maioria dos casos, o TCP é a escolha certa.
â € ¢ Port - Cada aplicativo servidor precisa de uma porta dedicada para escutar. As portas abaixo de 1024 são reservadas
e nunca deve ser usado, a menos que implemente um protocolo que tenha uma porta atribuída abaixo de 1024.
Uma vez decididas as perguntas, os comandos, respostas e respostas precisam ser projetados.
https://translate.googleusercontent.com/translate_f 128/261
22/04/2020 Indy em Profundidade
Page 78
75 Indy em Profundidade
Este projeto foi projetado para ser o mais simples possível. Código postal (CEP para American
pesquisa) permitirá que um cliente pergunte a um servidor de código postal qual cidade e estado é um código postal
atribuído a.
Os dados de amostra que o servidor usa são códigos postais dos EUA, chamados códigos postais. O protocolo
também pode lidar com outros códigos postais, mas os códigos postais dos EUA estavam disponíveis no momento da demonstração
construção.
Para aqueles de fora dos Estados Unidos que talvez não estejam familiarizados com os códigos postais, um código postal é
código postal que especifica uma área de entrega postal. Os códigos postais são numéricos e têm cinco dígitos. Fecho eclair
os códigos também podem conter mais quatro dígitos opcionais adicionais no formato 16412-0312. Esses tipos
são chamados Zip + 4. Os quatro dígitos adicionais especificam informações de entrega local e não são necessários
para localizar uma cidade.
â € ¢ Comandos de texto
â € ¢ TCP
â € ¢ Porta: 6000. A porta 6000 Ã © uma porta comumente usada no Indy para demos. Não tem significado.
https://translate.googleusercontent.com/translate_f 129/261
22/04/2020 Indy em Profundidade
â € ¢ Ajuda
â € ¢ Pesquisa <Código Postal 1> <Código Postal 2> ...
â € ¢ Sair
Como o NNTP suporta o envio e o recebimento de mensagens em um protocolo, o NNTP será consultado em
várias vezes neste documento para seu benefício.
10.8.1 Ajuda
A ajuda é um comando comumente implementado e tem pouco uso para clientes automatizados. A ajuda é útil para
humanos que estão testando ou interagindo manualmente com servidores. Quase todos os servidores implementam alguma forma
de ajuda básica.
A ajuda é útil para determinar quais comandos e possíveis comandos de extensão que um servidor
Page 79
Protocolos de implementação 76
apoia.
Socorro
100 comandos legais
nome do usuário authinfo | senha senha
https://translate.googleusercontent.com/translate_f 130/261
22/04/2020 Indy em Profundidade
artigo [MessageID | Number]
body [MessageID | Number]
verifique MessageID
encontro
grupo de notícias do grupo
head [MessageID | Number]
Socorro
eu tenho
último
lista [ativo | tempos ativos | grupos de notícias | assinaturas]
grupo de notícias do grupo de listas
fluxo de modo
leitor de modo
newgroups aaaamdd hhmmss [GMT] [<distribuições>]
grupos de notícias de notícias recentes yymmdd hhmmss [GMT] [<distribuições>]
Próximo
postar
escravo
stat [MessageID | Number]
pegue seu MessageID
xgtitle [group_pattern]
cabeçalho xhdr [range | MessageID]
xover [intervalo]
intervalo de cabeçalho xpat | MessageID pat [morepat ...]
.
Para o protocolo de código postal, o servidor deve responder com os mesmos 100, mais o texto apropriado.
10.8.2 Pesquisa
O comando de pesquisa aceita um ou mais códigos postais para pesquisa e retorna as cidades associadas
com eles. Os dados são retornados no formato de resposta RFC. Se nenhuma entrada correspondente for encontrada, não será
devolvida. A resposta para um comando de pesquisa bem-sucedida é "200 Ok".
Exemplo:
Mesmo que nenhuma entrada correspondente seja encontrada, a pesquisa responderá com "200 Ok".
pesquisa 99999
200 Ok
.
https://translate.googleusercontent.com/translate_f 131/261
22/04/2020 Indy em Profundidade
Esta é uma decisão de design. Se a pesquisa aceitasse apenas um parâmetro, seria melhor retornar 200 se um
foi encontrada uma correspondência e um código de erro 4XX se nenhuma correspondência for encontrada. Como a pesquisa pode retornar parcial
dados válidos, é melhor sempre retornar 200.
Page 80
77 Indy em Profundidade
200 Ok
37642: CHURCH HILL, TN
.
Se o protocolo retornasse um código de erro, dados válidos seriam ignorados. Essa decisão de projeto permite que o
servidor para retornar dados aos quais ele pode fazer referência sem bloquear com um erro.
10.8.3 Sair
Este comando de saída é muito direto. Sair indica que o cliente está prestes a terminar a sessão e
desconectar.
Sair
205 conexão de fechamento - adeus!
Sair
201-Paka!
201 2 pedidos processados.
https://translate.googleusercontent.com/translate_f 132/261
22/04/2020 Indy em Profundidade
O protocolo de código postal responde com uma resposta de várias linhas. Isso não é definido pelo próprio protocolo. Qualquer
A resposta RFC pode ser uma resposta única ou com várias linhas. Indy analisa os dois tipos automaticamente.
https://translate.googleusercontent.com/translate_f 133/261
22/04/2020 Indy em Profundidade
Page 81
Seção
https://translate.googleusercontent.com/translate_f 134/261
22/04/2020 Indy em Profundidade
Proxies
XI
Page 82
79 Indy em Profundidade
11 Proxies
Uma pergunta comum é "Como uso o Indy com um proxy?". Embora se esperasse que uma solução fácil
resposta poderia ser dada. Essa resposta não está disponível porque existem muitos tipos diferentes de
proxies. Alguns protocolos também têm seu próprio método de negociação de proxies. O mais comum
tipos de proxies serão explicados.
https://translate.googleusercontent.com/translate_f 135/261
22/04/2020 Indy em Profundidade
Proxies e firewalls desempenham funções semelhantes, mas têm objetivos diferentes. Porque eles compartilham papéis semelhantes,
eles podem ser usados para executar as funções uns dos outros e geralmente são agrupados como combinação
proxies de firewall.
â € ¢ Transparente
â € ¢ NÃ £ o transparente
Embora os proxies transparentes não tenham efeito sobre os clientes, eles afetam os servidores. Na maioria dos casos, servidores
por trás desses proxies estão ocultos do mundo exterior. Para permitir que servidores sejam acessados a partir do
o outro lado das portas proxy deve ser mapeado de fora para dentro.
A rede interna é definida como o lado da rede em que a rede local existe e o exterior
rede é definida como a rede ou rede externa que é o alvo da rede interna.
Por causa da rota bloqueada, todo acesso deve ser direcionado através de portas mapeadas. Portas são atribuídas
em um servidor local que tenha acesso ao mundo externo. Esse servidor passa os dados para frente e para trás
https://translate.googleusercontent.com/translate_f 136/261
22/04/2020 Indy em Profundidade
entre a rede externa e interna. A desvantagem das portas mapeadas é que cada porta é mapeada
para um host e porta remotos fixos. Para protocolos como correio e notícias, os quais os servidores podem ser
determinado de antemão, isso funciona muito bem. No entanto, para protocolos como HTTP, esse método não pode ser
utilizado porque os locais remotos não podem ser conhecidos antecipadamente.
As portas mapeadas também podem ser usadas para mapear portas da rede externa para a rede interna. Mapeado
As portas são frequentemente usadas em conjunto com proxies NAT para expor servidores à rede externa.
Page 83
Proxies 80
Usando o método User @ Site, todas as sessões de FTP são conectadas a um servidor proxy local. O proxy
finge ser um servidor FTP. O servidor proxy intercepta e interpreta as solicitações de FTP. Quando o
proxy pede o nome do usuário em vez de enviar apenas o nome do usuário, o nome do usuário e o FTP desejado
servidor são enviados como o nome de usuário no formato nome de usuário @ ftpsite. O proxy então se conecta ao
site FTP desejado e intercepta os comandos de transferência.
Para cada comando de transferência, o proxy mapeia dinamicamente uma porta local para a transferência de dados e
modifica as informações de transferência retornadas ao cliente. O cliente FTP contata o proxy em vez disso
de acessar diretamente o servidor FTP real. Por causa das traduções, o cliente FTP não sabe
que um proxy está envolvido.
Por exemplo, dado um site FTP de ftp.atozedsoftware.com, um nome de usuário de joe e uma senha de
smith, uma sessão FTP normal seria configurada da seguinte maneira:
Anfitrião: ftp.atozedsoftware.com
Usuário: joe
Senha: smith
https://translate.googleusercontent.com/translate_f 137/261
22/04/2020 Indy em Profundidade
Se existir um proxy User @ Site e o nome do proxy do host for corpproxy, a sessão FTP será
configurado assim:
Anfitrião: corpproxy
Usuário: [email protected]
Senha: smith
11.2.1 MEIAS
SOCKS é um proxy que não requer nenhuma alteração no protocolo de nível superior, mas funciona no
Nível TCP. Para que os protocolos usem um proxy SOCKS, o software deve implementá-lo no nível TCP.
Se o software não suportar explicitamente o proxy SOCKS, ele não poderá ser usado com um firewall SOCKS. UMA
Muitos softwares populares, como navegadores e ICQ, oferecem suporte a SOCKS, mas a maioria dos softwares
não. Por esse motivo, o SOCKS geralmente deve ser implantado em conjunto com servidores internos, mapeados
portas, outros proxies ou uma combinação.
Para que o software suporte SOCKS, em vez de se conectar ao servidor de destino, ele primeiro se conecta ao
Proxy SOCKS. Em seguida, passa sobre um registro de dados que contém o servidor de destino e opcional
credenciais de autenticação de proxy. O servidor SOCKS, então, encapsula dinamicamente a conexão com o
servidor.
Como o protocolo SOCKS funciona dinamicamente no registro passado durante a conexão, o SOCKS é
altamente configurável e muito flexível.
https://translate.googleusercontent.com/translate_f 138/261
22/04/2020 Indy em Profundidade
Page 84
81 Indy em Profundidade
Muitos ambientes corporativos protegeram completamente suas redes internas e apenas permitiram
acesso ao mundo exterior usando HTTP e correio. O correio é fornecido usando servidores de correio internos e
O HTTP é fornecido usando um proxy HTTP. Por causa disso, o HTTP se tornou o "firewall final"
amigável "e é por isso que tantos protocolos mais recentes podem usar HTTP como transporte. SOAP e Web
serviços são exemplos notáveis.
https://translate.googleusercontent.com/translate_f 139/261
22/04/2020 Indy em Profundidade
Page 85
https://translate.googleusercontent.com/translate_f 140/261
22/04/2020 Indy em Profundidade
Seção
XII
IOHandlers
https://translate.googleusercontent.com/translate_f 141/261
22/04/2020 Indy em Profundidade
Page 86
83 Indy em Profundidade
12 IOHandlers
O Indy é personalizável e extensível de várias maneiras, sem a necessidade de modificar a fonte do Indy
código diretamente. Um exemplo dessa extensibilidade é o IOHandlers. Os IOHandlers permitem que você use qualquer E / S
fonte com Indy. Os IOHandlers devem ser usados quando você deseja usar um mecanismo de E / S alternativo ou
crie um novo mecanismo de transporte.
Os IOHandlers executam todas as E / S (Entrada / Saída) para Indy. O Indy não executa mais suas próprias E / S
fora de um IOHandler.
Um IOHandler é usado para enviar e receber dados TCP brutos para componentes Indy.
Os IOHandlers permitem definir classes que manipulam a entrada / saída do Indy. Normalmente, todas as E / S são feitas
via soquete e manipulado pelo IOHandler padrão, TIdIOHandlerSocket .
Cada cliente TCP em Indy possui uma propriedade IOHandler que pode ser atribuída a um IOHandler, assim como
cada conexão do servidor. Se um IOHandler não for especificado, uma instância implícita de um TIdIOHandlerSocket
será criado automaticamente e usado pelo cliente TCP. TIdIOHandlerSocket implementa E / S usando um
Soquete TCP. Indy inclui IOHanders adicionais: TIdIOHandlerStream e TIdSSLIOHandlerSocket
também.
Outros IOHandlers podem ser criados para permitir que o Indy use praticamente qualquer fonte de E / S que você possa imaginar.
https://translate.googleusercontent.com/translate_f 142/261
22/04/2020 Indy em Profundidade
Atualmente, o Indy suporta apenas soquetes, fluxos e SSL como fontes de E / S, mas os IOHandlers permitem muitos
outras possibilidades também. Embora não haja planos atuais, os IOHandlers podem ser implementados para
Suporte para tunelamento, IPX / SPX, RS-232, USB ou Firewire. O Indy não restringe suas opções de E / S e, por
O uso do IOHandlers Indy permite escolher qualquer E / S necessária.
Page 87
https://translate.googleusercontent.com/translate_f 143/261
22/04/2020 Indy em Profundidade
IOHandlers 84
12.1.1 TIdIOHandlerSocket
TIdIOHandlerSocket é o IOHandler padrão. Se nenhum IOHandler for especificado, um implícito
TIdIOHandlerSocket será criado para uso. TIdIOHandlerSocket manipula todas as E / S relacionadas a um TCP
tomada.
Normalmente, o TIdIOHandlerSocket não é usado explicitamente, a menos que sejam necessárias opções avançadas.
12.1.2 TIdIOHandlerStream
TIdIOHandlerStream é usado para depuração e teste de caixa. Usando-o, sessões TCP ao vivo podem ser
gravados à medida que interagem com os servidores. Posteriormente, como parte de uma caixa, a sessão pode ser "repetida". The Indy
Os componentes não sabem que não estão conversando com um servidor real usando uma conexão real.
Essa é uma ferramenta de depuração muito poderosa, além de uma ferramenta de teste de controle de qualidade. Se um cliente tiver um problema, um
compilação especial pode ser enviada ou um recurso de depuração ativado para registrar a sessão. Usando os arquivos de log, você pode
em seguida, reconstrua a sessão do cliente em um ambiente de depuração local.
12.1.3 TIdSSLIOHandlerSocket
TIdSSLIOHandlerSocket é usado para implementar o suporte SSL. Normalmente criptografia e compactação
manipuladores seriam implementados usando Interceptações em vez de IOHandlers. No entanto, a biblioteca SSL que
Indy usa (OpenSSL) aceita um identificador de soquete e faz a comunicação de soquete na biblioteca
em vez de traduzir dados recebidos e enviados por Indy. Por esse motivo, é implementado como um
IOHandler porque a biblioteca lida com a E / S. TIdSSLIOHandlerSocket é descendente de
TIdIOHandlerSocket .
O Speed Debugger consiste em um formulário principal e um IOHandler personalizado. O Speed Debugger usa um mapeado
componente da porta para proxy do tráfego HTTP para um servidor da web especificado. Um navegador se conecta ao Speed
Depurador e Speed Debugger recupera uma página da web do servidor especificado, mas a retorna para
https://translate.googleusercontent.com/translate_f 144/261
22/04/2020 Indy em Profundidade
A caixa de combinação é usada para selecionar a velocidade para restringir a conexão e consiste nos seguintes
escolhas A velocidade restrita simulada é exibida entre parênteses.
â € ¢ Apache (Ilimitado)
â € ¢ Acesso discado (28,8k baud)
â € ¢ IBM PC XT (9600 baud)
â € ¢ Commodore 64 (2400 baud)
â € ¢ Microsoft IIS em uma PIII-750 e 1 GB de RAM (300 baud)
Quando o botão Teste é pressionado, o Speed Debugger inicia o navegador padrão com o URL
http://127.0.0.1:8081/. Isso fará com que o navegador faça seus pedidos do Speed Debugger. Rapidez
O depurador escuta na porta 8081 para evitar conflitos com quaisquer servidores Web locais existentes.
Page 88
85 Indy em Profundidade
No método .Recv, o .Recv herdado é chamado para receber dados. Em seguida, com base no especificado
limite de velocidade, o atraso apropriado é calculado. Se o atraso calculado for maior que o tempo real
a chamada herdada .Recv demorou para ser executada, uma chamada para suspensão é feita com a diferença. Pode parecer
complicado, mas é realmente simples. O método .Recv aparece abaixo.
https://translate.googleusercontent.com/translate_f 146/261
22/04/2020 Indy em Profundidade
Page 89
https://translate.googleusercontent.com/translate_f 147/261
22/04/2020 Indy em Profundidade
Seção
XIII
Intercepta
Page 90
https://translate.googleusercontent.com/translate_f 148/261
22/04/2020 Indy em Profundidade
87 Indy em Profundidade
13 Intercepta
Um Intercept está em um nível mais alto que um IOHandler e é usado para modificar ou capturar dados independentemente
de sua origem ou destino. As interceptações são usadas para registro, depuração e criptografia. De outros
possíveis usos são compressão ou análise estatística.
As interceptações foram drasticamente alteradas no Indy 9.0. No Indy 8.0, o Intercepts poderia fornecer algumas
funcionalidade muito limitada de um IOHandler. Interceptações podem transformar dados já recebidos ou dados
antes de enviar. Interceptações não suportam mais nenhuma funcionalidade IOHandler, pois o novo IOHandler
As classes lidam com toda essa funcionalidade.
As interceptações ainda podem realizar a transformação de dados e de uma maneira muito mais flexível do que no Indy 9.0. Indy
As capacidades de transformação do 8.0 tinham muitas limitações, como os dados eram necessários para permanecer o
mesmo tamanho. Isso impossibilitou a implementação da compactação como interceptação e limitação
intercepta o log e a compactação que não alteraram o tamanho dos dados.
Intercepta o trabalho permitindo que os dados sejam modificados após serem recebidos de um IOHandler ou
modificado antes de ser enviado para um IOHandler. Atualmente, as interceptações são usadas para implementar
componentes de depuração. Interceptações também podem ser usadas para implementar criptografia, compactação, estatística
coletores ou limitadores de largura de banda.
13.1 Interceptações
Intercepta a interceptação de dados de entrada e saída e permite que eles sejam registrados ou modificados. Interceptações permitem
dados recebidos a serem modificados após serem lidos da rede, mas antes retornados ao usuário.
As interceptações também permitem que os dados de saída sejam modificados após serem recebidos pelo usuário, mas antes de serem recebidos.
É transmitido. Interceptações podem ser usadas para implementar log, criptografia e compactação.
As interceptações de clientes são baseadas em conexão e são por conexão. Eles também podem ser usados com o servidor se
atribuído a conexões individuais.
Observe que as interceptações no Indy 9 diferem das interceptações do Indy 8. No Indy 8, o Interceptos executou um
papel combinado de Intercept e IOHandler. Isso dificultava a separação de Intercept e
https://translate.googleusercontent.com/translate_f 149/261
22/04/2020 Indy em Profundidade
Funcionalidade IOHandler. O Intery 8's Intercepts também não pôde alterar o tamanho dos dados e, portanto, poderia
Não execute compactação.
13.2 Log
O Indy 8.0 tinha um componente de log que poderia usar destinos diferentes. Componentes de registro do Indy 9.0
agora são baseados em uma nova classe de log comum e são classes de log especializadas. O comum
A classe logging também apresenta propriedades e funcionalidades, como poder registrar o horário
Além dos dados.
Todas as classes de log são implementadas como interceptações. Isso significa que eles capturam os dados recebidos depois que
foi lido da fonte de entrada e antes que os dados enviados sejam gravados na saída.
â € ¢ TIdLogEvent - TIdLogEvent dispara eventos quando dados são enviados, recebidos ou ocorre uma mensagem de status.
TIdLogEvent é útil para implementar o log personalizado sem a necessidade de implementar um novo log
Page 91
Intercepta 88
classe.
â € ¢ TIdLogFile - Registra dados em um arquivo de dados.
â € ¢ TIdLogDebug - Registra dados na janela de depuraçà £ o no Windows e no console no Linux. Isso também
marca os dados como dados recebidos, dados enviados ou informações de status. TidLogDebug é útil para simples
depuração.
â € ¢ TIdLogStream - nà £ o comenta ou marca os dados como as outras classes de log. Em vez disso
apenas grava dados brutos nos fluxos especificados. O TIdLogStream tem muitos usos, mas é extremamente
útil para teste de controle de qualidade e depuração remota.
https://translate.googleusercontent.com/translate_f 151/261
22/04/2020 Indy em Profundidade
Page 92
Seção
https://translate.googleusercontent.com/translate_f 152/261
22/04/2020 Indy em Profundidade
XIV
Depuração
Page 93
https://translate.googleusercontent.com/translate_f 153/261
22/04/2020 Indy em Profundidade
Depuração 90
14 Depuração
Geralmente, os clientes são muito fáceis de depurar, especialmente quando comparados aos servidores. Os clientes lidam apenas com um
conexão única e geralmente pode ser depurada usando técnicas normais de depuração. Nesta seção, um
serão examinadas algumas dicas úteis que são úteis para clientes e servidores.
14.1 Registro
Uma maneira realmente fácil de ver o que está acontecendo com um cliente sem rastrear o código é usar o comando
TIdLogDebug ou TIdLogFile. O TIdLogDebug registrará diretamente na janela de depuração e é muito útil
para assistir os dados que o cliente está enviando e recebendo em tempo real. Se você não precisa assistir
o tráfego em tempo real, use um TIdLogFile. Depois que o cliente terminar, você poderá ver o conteúdo
do arquivo para ver o que ocorreu durante a sessão.
https://translate.googleusercontent.com/translate_f 154/261
22/04/2020 Indy em Profundidade
Para fazer isso, use um TIdLogStream para registrar os dados recebidos em um arquivo. Você também pode gravar o
dados que o cliente enviou em um arquivo separado, mas você não precisará disso, a menos que deseje analisá-lo
manualmente. Ao receber o arquivo, você pode anexar um componente TIdIOHandlerStream ao cliente.
Os IOHandlers também têm outro uso realmente interessante. Esse uso é registro e resposta. Uma sessão ao vivo pode ser
gravado usando os componentes de log e reproduzido posteriormente usando IOHandlers de fluxo. Imagine que você
tem um cliente que está com problemas, mas você não pode reproduzir os problemas deles e não pode estar ligado
local. Você pode fazer com que eles registrem uma sessão completa em um conjunto de arquivos e, em seguida, usando IOHandlers de fluxo
repita completamente a sessão na sua máquina de desenvolvimento. A equipe do Indy está começando a usar esses
como parte do processo de controle de qualidade e do conjunto de testes em caixa. Pretendo cobrir isso em uma parcela futura.
Page 94
https://translate.googleusercontent.com/translate_f 155/261
22/04/2020 Indy em Profundidade
Seção
XV
Concorrência
https://translate.googleusercontent.com/translate_f 156/261
22/04/2020 Indy em Profundidade
Page 95
Concorrência 92
15 Concorrência
Em um ambiente encadeado, os recursos devem ser protegidos para que os recursos não sejam corrompidos por
permitindo acesso por mais de um thread em um determinado momento.
Simultaneidade e threads estão interligados, e pode ser difícil escolher quais aprender primeiro. Esse texto
abordará primeiro os problemas de simultaneidade que criarão o entendimento adequado para os tópicos de aprendizado.
15.1 Terminologia
https://translate.googleusercontent.com/translate_f 157/261
22/04/2020 Indy em Profundidade
Page 96
93 Indy em Profundidade
https://translate.googleusercontent.com/translate_f 158/261
22/04/2020 Indy em Profundidade
15.1.1 Concorrência
Simultaneidade é o estado de muitas tarefas que ocorrem ao mesmo tempo. Quando a simultaneidade é
implementado adequadamente, pode ser considerado "harmonia". Quando implementado mal, "caos".
Na maioria dos casos, uma tarefa é um encadeamento. No entanto, as tarefas também podem ser processos ou fibras.
A linha que divide os dois geralmente é boa, e o uso de técnicas apropriadas é a chave.
15.1.2 Contenção
O que exatamente é a contenção? A contenção ocorre quando mais de uma tarefa tenta acessar um único recurso
ao mesmo tempo.
Aqueles de vocês que cresceram em uma família numerosa definitivamente entendem a disputa, e talvez um exemplo
vai explicar de forma concisa. Imagine o que acontece na família de seis filhos quando mamãe coloca uma pizza pequena
a mesa para o jantar. Isso é contenda.
Sempre que várias tarefas simultâneas precisarem acessar os dados de maneira de leitura / gravação, acesse os dados
deve ser controlado para proteger sua integridade. Se o acesso não for controlado, duas ou mais tarefas poderão "travar"
quando um tenta ler uma variável enquanto outro tenta escrever nela simultaneamente. Se uma tarefa estiver escrevendo
enquanto outra estiver lendo, a única leitura poderá recuperar dados parcialmente gravados e receber dados corrompidos.
Normalmente, isso não causará nenhuma exceção e simplesmente causará erros posteriormente no programa.
Problemas de contenção geralmente não ocorrem em implementações de baixo volume e, portanto, frequentemente não ocorrem
durante o desenvolvimento. Devido a essa técnica adequada, o teste de carga deve ser realizado durante
desenvolvimento. Caso contrário, é um pouco como jogar roleta russa, e os problemas só ocorrerão
aleatoriamente durante o desenvolvimento, mas frequentemente durante a implantação.
https://translate.googleusercontent.com/translate_f 159/261
22/04/2020 Indy em Profundidade
controlada para proteger sua integridade. Isso pode ser intimidador para programadores que não estão familiarizados com o encadeamento.
No entanto, a maioria dos servidores não requer dados globais. Aqueles que normalmente precisam apenas ler os dados
após ter sido inicializado durante a inicialização do programa. Desde que não haja acesso de gravação, os threads podem
leia dados globais sem efeitos colaterais.
Além disso, os recursos podem ser gravados antes de qualquer possível leitura. Isso permite a inicialização de
recursos na inicialização, antes que as tarefas que o acessam sejam iniciadas.
Page 97
Concorrência 94
Normalmente, tarefas como ler ou gravar em um campo inteiro ou booleano são consideradas atômicas
operações à medida que são compiladas em uma única instrução de movimentação. No entanto, é minha recomendação que você
nunca confie em operações atômicas porque, em alguns casos, mesmo uma gravação em um número inteiro ou booleano pode
envolveu mais de uma única operação, dependendo de onde os dados foram lidos primeiro. Além disso, este
https://translate.googleusercontent.com/translate_f 160/261
22/04/2020 Indy em Profundidade
depende do conhecimento interno do compilador, que está sujeito a alterações sem aviso prévio. Depender
operações atômicas no nível do código-fonte produzirão código que será problemático no futuro e
pode agir de maneira bastante diferente em máquinas com vários processadores ou outros sistemas operacionais.
Vi operações atômicas defendidas fortemente. No entanto, uma próxima edição muito proeminente que
prova que meu ponto é .net. Quando seu código-fonte é compilado primeiro para IL e depois recompilado para
possibilidade de código de máquina em diferentes plataformas meus diferentes fornecedores, você pode honestamente ter certeza de que seu
linha de código fonte será uma operação atômica no final?
O Windows suporta um conjunto de funções conhecidas como funções intertravadas. A utilidade das funções
é bastante limitado e consiste em funcionalidade simples em números inteiros, como incremento, decremento, adição,
swap e swap-compare.
O número de funções varia de acordo com as diferentes edições do Windows e pode causar conflitos em versões mais antigas.
versões do Windows. Na maioria dos aplicativos, eles oferecem pouco benefício de desempenho.
Devido aos fatores combinados de uso limitado, suporte variável e pouco benefício no desempenho, é
aconselhado a usar os equivalentes Indy threadsafe.
O Windows também contém suporte para objetos especiais IPC (comunicação entre processos) que possuem Delphi
invólucros. Esses objetos são extremamente úteis para segmentação e IPC.
A proteção explícita normalmente usa um objeto de proteção de recurso. Em resumo, uma proteção de recursos
O objeto limita o acesso a um recurso a uma tarefa por vez. Um objeto de proteção de recurso, na verdade, não
limitar o acesso a um recurso; caso isso aconteça, ele precisará saber detalhes sobre cada recurso
https://translate.googleusercontent.com/translate_f 161/261
22/04/2020 Indy em Profundidade
tipo.
sinal.Em vezobjeto
Cada disso,deagem comodeum
proteção sinal deimplementa
recursos trânsito e oum
código
tipo édiferente
adaptadodepara
sinalobedecer e fornecer
de tráfego entrada ao tráfego
usando diferentes
lógica, entradas diferentes e níveis variáveis de sobrecarga. Isso permite uma proteção de recurso diferente
Page 98
95 Indy em Profundidade
objeto a ser escolhido para melhor atender a diferentes tipos de recursos e situações.
Os objetos de proteção de recursos existem de várias formas e são abordados individualmente posteriormente.
Seções críticas podem ser usadas para controlar o acesso aos recursos globais. Seções críticas são leves
e são implementados na VCL em TCriticalSection. Em resumo, uma seção crítica permite um único thread
em um aplicativo multithread para bloquear temporariamente a execução de todos os outros threads tentando
use a mesma seção crítica. As seções críticas funcionam como um semáforo que só fica verde quando o
estrada à frente está livre de todos os veículos. Seções críticas podem ser usadas para garantir o único segmento em
a qualquer momento está executando um bloco de código. Por isso, blocos protegidos por seções críticas
deve ser mantido o menor possível, pois pode afetar gravemente o desempenho, se não for usado adequadamente.
Por esse motivo, cada bloco exclusivo também deve usar seu próprio TCriticalSection e, em vez de reutilizar um
aplicação única ampla TCriticalSection.
Para entrar em uma seção crítica, o método Enter é chamado e Leave é usado para sair da seção crítica.
O TCriticalSection também possui métodos de aquisição e liberação que fazem exatamente a mesma coisa que Enter e
Deixe respectivamente.
Imagine um servidor que precise registrar informações sobre clientes logados e exibir as informações em
a linha principal. Uma opção seria usar a sincronização. No entanto, usar esse método negativamente
impactar o desempenho dos encadeamentos de conexão se muitos clientes efetuarem login ao mesmo tempo. Dependendo
de acordo com as necessidades do servidor, uma opção melhor pode ser registrar as informações e ler o thread principal
as informações usando um timer. O código a seguir é um exemplo dessa técnica que utiliza uma crítica
seção.
https://translate.googleusercontent.com/translate_f 162/261
22/04/2020 Indy em Profundidade
var
GLogCS: Seção TCritical;
GUserLog: TStringList;
inicialização
GLogCS: = TCriticalSection.Create;
GUserLog: = TStringList.Create;
finalização
FreeAndNil (GUserLog);
FreeAndNil (GLogCS);
fim .
No evento Connect, o nome de usuário é lido em uma variável temporária antes de inserir a chave crítica.
seção. Isso é feito para evitar a possibilidade de um cliente lento bloquear o código na seção crítica.
Isso permite que a comunicação de rede seja realizada antes de entrar na seção crítica. Manter
desempenho no máximo, o código na seção crítica é mantido no mínimo absoluto.
Page 99
Concorrência 96
https://translate.googleusercontent.com/translate_f 163/261
22/04/2020 Indy em Profundidade
O evento Timer1Timer é acionado no thread principal por um timer no formulário principal. O intervalo do
O temporizador pode ser reduzido para fornecer uma atualização mais frequente, mas pode potencialmente diminuir a velocidade do
aceitação de conexões. Se a funcionalidade do log for estendida para outras partes do servidor em
Além de apenas registrar a conexão do usuário, maior o potencial de um gargalo. o
quanto maior o intervalo, menos tempo real a atualização da interface do usuário. No entanto, muitos servidores têm
nenhuma interface, e as que fazem, a interface é normalmente secundária e tem uma prioridade muito menor
do que atender clientes, portanto, é uma troca perfeitamente aceitável.
TCriticalSection está na unidade SyncObjs. A unidade SyncObjs não está incluída no Delphi 4 Standard
Edição. Se você estiver usando o Delphi 4 Standard Edition, há um arquivo SyncObjs.pas disponível no Indy
site que não implementa tudo no SyncObjs.pas da Borland, mas implementa o
Classe TCriticalSection.
No exemplo anterior, TCriticalSection foi usado para proteger o acesso aos dados globais. Naqueles
casos, os dados globais sempre foram atualizados. No entanto, se os dados globais estiverem sendo acessados algumas vezes como
somente leitura, o uso de um TMultiReadExclusiveWriteSynchronizer pode produzir um código-fonte mais eficiente.
TMultiReadExclusiveWriteSynchronizer é uma classe longa e difícil de ler. Por isso, simplesmente
ser referido como TMREWS.
A vantagem de usar um TMREWS é que ele permite a leitura simultânea por vários threads, enquanto
agindo como uma seção crítica e permitindo apenas acesso a um thread durante as leituras. A desvantagem é
o TMREWS é mais caro de usar.
Em vez de Enter / Adquirir e Sair / Liberar, o TMREWS possui os métodos BeginRead, EndRead,
BeginWrite e EndWrite.
15.2.4.2.1 Notas especiais no TMREWS
Antes do Delphi 6, o TMultiReadExclusiveWriteSynchronizer tinha um problema pelo qual durante uma promoção
de um bloqueio de leitura para um bloqueio de gravação pode causar um bloqueio morto. Por isso, você nunca deve usar isso
recurso de promover um bloqueio de leitura para um bloqueio de gravação, mesmo que ele esteja documentado como capaz de fazê-lo.
Se você precisar dessa funcionalidade, há uma solução alternativa. A solução é liberar o bloqueio de leitura e
obtenha um bloqueio de gravação. No entanto, depois de obter o bloqueio de gravação, verifique novamente
a condição que primeiro o levou a desejar um bloqueio de gravação. Se ainda existir, execute o que for necessário,
https://translate.googleusercontent.com/translate_f 164/261
22/04/2020 Indy em Profundidade
Page 100
97 Indy em Profundidade
Como o TMREWS foi atormentado por problemas, meu conselho é simplesmente evitá-lo. Se você fizer
decidir usá-lo, certifique-se de que seja realmente a melhor opção e tenha obtido um
versão corrigida que não é propensa a comportamento de conflito.
O uso adequado de uma TCriticalSection na maioria dos casos produzirá resultados quase tão rápidos e, em alguns casos
resultados mais rápidos. Aprenda a otimizar suas TCriticalSection, quando necessário, como uso inadequado de um
TCriticalSection afetará significativamente o desempenho.
A chave para qualquer proteção de recurso é usar vários controladores de recursos e manter as seções de bloqueio
pequeno. Quando tais situações podem ser estabelecidas, uma seção crítica deve sempre ser usada, pois
é mais leve e mais rápido que um TMREWS. Em geral, sempre use seções críticas, a menos que você possa
https://translate.googleusercontent.com/translate_f 165/261
22/04/2020 Indy em Profundidade
Como mencionado, as seções críticas anteriores são mais leves e, portanto, mais rápidas. Seções críticas são
implementado pelo sistema operacional. O sistema operacional os implementa usando recursos muito rápidos e
pequenas instruções de montagem.
A classe TMREWS é mais complicada e, portanto, possui mais sobrecarga. Ele deve gerenciar listas de
solicitadores para gerenciar adequadamente o mecanismo de bloqueio de estado duplo.
Para demonstrar a diferença, um projeto de exemplo chamado ConcurrencySpeed.dpr foi criado. isto
realiza três medições simples do seguinte:
Ele executa esses testes executando-os dentro de um loop de contador por um período especificado de vezes. Para
Para fins de teste, o padrão é 100.000 iterações. Nos meus testes, os seguintes resultados foram obtidos (em
milissegundos):
TCriticalSection: 20
TMREWS (bloqueio de leitura): 150
TMREWS (Bloqueio de gravação): 401
Naturalmente, as medições são específicas da máquina. No entanto, as diferenças entre eles é o que é
importante aqui, não os números reais. Pode-se observar que, idealmente, um bloqueio de leitura em um TMREWS é 7,5
vezes mais lento que uma seção crítica e que um bloqueio de gravação é 20 vezes mais lento.
Note-se também que, embora a seção crítica tenha apenas uma medição, o desempenho do TMREWS
degrada sob uso simultâneo. Os testes realizados aqui foram simplesmente em loop e nenhum outro
os solicitantes estavam solicitando ou tinham bloqueios existentes para o TMREWS lidar. Numa situação real, o
O TMREWS seria ainda mais lento que os números ótimos mostrados aqui.
https://translate.googleusercontent.com/translate_f 166/261
22/04/2020 Indy em Profundidade
Page 101
Concorrência 98
15.2.4.5 Mutexes
Os mutexes funcionam quase de forma idêntica nas seções críticas. A diferença com um mutex é que é mais
versão poderosa de uma seção crítica com mais recursos e, portanto, mais sobrecarga.
Os mutexes têm os recursos adicionais de serem nomeados, atribuídos atributos de segurança e serem
acessível entre processos.
Mutexes podem ser usados para comunicação entre threads, mas raramente são necessários. Mutexes são
projetado e normalmente usado para comunicação entre processos.
15.2.4.6 Semáforos
Um semáforo é semelhante a um mutex, mas, em vez de permitir apenas um participante, permite vários participantes.
O número de participantes que ele permite é especificado quando o semáforo é criado.
Imagine que um mutex é um guarda de segurança que está protegendo o acesso a uma máquina bancária de dinheiro
(ATM). Somente uma pessoa de cada vez pode usá-lo, e o guarda de segurança está protegendo a máquina contra
a fila de pessoas que desejam usá-lo ao mesmo tempo.
Nesse caso, um semáforo seria relevante se fossem instalados 4 caixas eletrônicos. Nesse caso, a segurança
O guarda permitiria que 4 pessoas de cada vez entrassem e usassem os caixas eletrônicos, mas não mais que 4 em um determinado momento.
15.2.4.7 Eventos
Eventos são sinais que podem ser usados entre threads ou processos para notificar que algo está
ocorreu. Eventos podem ser usados para notificar outras tarefas quando algo for concluído ou precisar de ação.
https://translate.googleusercontent.com/translate_f 167/261
22/04/2020 Indy em Profundidade
As classes de thread safe podem ser tão simples quanto um inteiro seguro de thread ou tão complexas quanto um thread safe
base de dados. As classes seguras de encadeamento usam objetos seguros de encadeamento internamente para realizar sua função.
15.2.6 Compartimentalização
Compartimentalização é o processo de isolar dados e atribuí-los para serem usados apenas por um único
tarefa. Com os servidores, a compartimentalização geralmente é natural, pois cada cliente pode ser tratado por um
fio.
Page 102
https://translate.googleusercontent.com/translate_f 168/261
22/04/2020 Indy em Profundidade
Seção
XVI
Tópicos
https://translate.googleusercontent.com/translate_f 169/261
22/04/2020 Indy em Profundidade
Page 103
Tópicos 100
16 Tópicos
Imagine que seu computador é uma empresa com apenas uma linha telefônica. Porque existe apenas um telefone
https://translate.googleusercontent.com/translate_f 170/261
22/04/2020 Indy em Profundidade
linha, apenas uma pessoa pode usá-lo por vez. No entanto, se você instalar várias linhas telefônicas, outras pessoas poderão
faça chamadas telefônicas sem ser impedido por alguém que já esteja usando. Threads permitem que você
aplicativo para fazer mais de uma coisa por vez.
O encadeamento está disponível mesmo se você tiver apenas uma CPU. Na realidade, apenas um segmento está sendo executado a cada
tempo, no entanto, o sistema operacional interrompe preventivamente o encadeamento e alterna para outro.
Cada encadeamento é executado apenas por um período muito curto a cada passagem. Isso permite dezenas de milhares de
"fatias" para ocorrer por segundo. Como a troca é preventiva e imprevisível, para o software
os threads parecem estar em execução em paralelo e o software deve tomar precauções sobre isso.
Em vários sistemas de CPU, os threads podem realmente executar em paralelo, porém cada CPU pode, na realidade,
ainda executa apenas um encadeamento de cada vez.
16.2.1 Priorização
As prioridades de threads individuais podem ser ajustadas. Isso permite conexões de servidor individuais ou threads
clientes recebem mais ou menos tempo de CPU.
Se você aumentar a prioridade de todos os threads, não haverá muito efeito, pois ainda serão todos os
mesma prioridade. No entanto, eles podem ganhar tempo com os encadeamentos de outros processos. Você deve ter cuidado
quando você define prioridades de encadeamento para não defini-las muito altas, caso contrário, elas podem interferir
estão lidando com entrada e saída de hardware.
Na maioria dos casos, quando as prioridades do encadeamento são ajustadas em vez de aumentar a prioridade, você a diminui. este
é permitir que tarefas menos importantes rendam mais tempo às tarefas mais importantes.
As prioridades do encadeamento também podem ser úteis em servidores e, em alguns casos, você pode querer ajustar um encadeamento
prioridade com base no login. Se um administrador ou CEO fizer login, você poderá aumentar seu segmento
prioridade sobre o resto dos usuários.
16.2.2 Encapselamento
O uso de threads permite que cada tarefa seja independente e, portanto, menos propensa a interferir com outras
tarefas e dados associados.
https://translate.googleusercontent.com/translate_f 171/261
22/04/2020 Indy em Profundidade
Page 104
Se você já usou o Windows 3.1, provavelmente se lembra de como um aplicativo que se comporta mal pode
fácil derrubar todo o sistema. Threads evitam isso. Mas também vai além disso, diretamente
em programação. Sem threads, todas as tarefas teriam que ser realizadas nos mesmos caminhos de
código, criando complexidades extras. Com o encadeamento, cada tarefa pode ser separada em
seções independentes, facilitando a programação do código quando tarefas devem ser executadas
simultaneamente.
16.2.3 Segurança
Cada encadeamento pode ter seus próprios atributos de segurança individuais com base na autenticação ou em outros critérios.
Isso é especialmente útil em implementações de servidor em que cada usuário tem um encadeamento específico associado
com a conexão deles. Isso permite que o sistema operacional implemente a segurança adequada para o usuário,
restringir adequadamente o acesso a arquivos e outros objetos do sistema. Sem esse recurso, você teria
reimplementar a segurança, possivelmente deixando brechas desastrosas na segurança.
Outros processos usarão as outras CPUs, no entanto, assim como o sistema operacional. Certas chamadas que são
feitos no sistema operacional pelo seu programa são multiencadeados internamente e seu aplicativo será
receber um pequeno impulso com isso. Além disso, o tempo disponível para sua aplicação será maior
porque as outras CPUs podem lidar com outros aplicativos e diminuir a carga por CPU.
https://translate.googleusercontent.com/translate_f 172/261
22/04/2020 Indy em Profundidade
A melhor maneira de tirar proveito de várias CPUs, no entanto, é multiencadear seu aplicativo. este
não apenas permitirá que seu aplicativo seja distribuído corretamente entre as CPUs, mas também fornecerá mais CPU
tempo para seu aplicativo porque ele contém mais threads.
Com o encadeamento, cada tarefa pode ser programada como uma tarefa completa e o sistema operacional será
divida o tempo da CPU entre as tarefas.
Page 105
Tópicos 102
https://translate.googleusercontent.com/translate_f 173/261
22/04/2020 Indy em Profundidade
Como os threads não são completamente isolados um do outro, a comunicação entre eles também é
bastante fácil.
As variáveis de encadeamento são semelhantes às globais e são declaradas de maneira semelhante. A diferença é que um
global seria global para todos os threads, enquanto um threadvar será global para todo o código, mas específico para cada
fio. Ou seja, cada thread define seu próprio "espaço global".
As variáveis de encadeamento podem ser úteis quando é difícil passar referências a objetos entre bibliotecas ou
partes isoladas do código. No entanto, as variáveis de encadeamento também têm limitações. Variáveis de encadeamento não podem ser
usado ou declarado dentro dos pacotes. Sempre que possível, as variáveis de membro nas classes de encadeamento devem
ser usado em seu lugar. Eles têm uma sobrecarga mais baixa e estão disponíveis para uso em pacotes.
16.6.1 Roscável
Threadable significa que um item pode ser usado dentro de um thread ou usado por threads, se adequadamente
protegido usando a proteção de recursos. O item marcado em geralmente encadeado não possui
conhecimento de threads na maioria dos casos.
Se um item é encadeado, significa que ele pode ser usado por um único encadeamento de cada vez. Isso pode ser
realizado tornando-o local para um encadeamento na maioria dos casos ou como um item global protegido por recursos.
Exemplos comuns de itens encadeados são Inteiro, String, outros tipos ordinais, TList, TStringList, como
https://translate.googleusercontent.com/translate_f 174/261
22/04/2020 Indy em Profundidade
O item não pode fazer uso irrestrito de variáveis globais ou acessar diretamente os controles da GUI. o
O uso irrestrito (e muitas vezes desnecessário) de variáveis globais é o motivo mais comum para
componentes não são roscáveis.
16.6.2 Threadsafe
Threadsafe significa que o item tem conhecimento explícito de threads e fornece seu próprio recurso
proteção. Itens seguros para threads podem ser usados por um único ou vários threads sem nenhum recurso
proteção.
Page 106
Exemplos de classes threadsafe são o TThreadList da VCL, bem como todos os threadsafe da Indy
Aulas. Certos objetos do sistema operacional também são seguros para threads.
16.7 Sincronização
Sincronização é o processo de passar informações de threads secundários para o thread principal. o
O VCL suporta isso usando o método Sychronize no TThread.
16,8 TThread
TThread é a classe de encadeamento incluída na VCL e fornece uma boa implementação mediante
para construir threads.
https://translate.googleusercontent.com/translate_f 175/261
22/04/2020 Indy em Profundidade
Para implementar um encadeamento, uma classe é descendente de TThread e o método Execute é substituído.
16.9 TThreadList
TThreadList é uma implementação segura de thread do TList. TList pode ser usado por qualquer número de threads
sem a necessidade de protegê-lo do acesso simultâneo.
TThreadList funciona de forma semelhante ao TList, mas não é exatamente o mesmo. Alguns métodos, como Adicionar, Limpar e
Remover são os mesmos. No entanto, para outras operações, o TThreadList deve primeiro ser bloqueado usando o comando
Método LockList. O método LockList é uma função e retorna acesso direto ao TList interno.
Enquanto estiver bloqueado, todos os outros threads serão bloqueados. Por isso, é importante desbloqueá-lo novamente, pois
assim que possível.
É muito importante que a lista seja sempre desbloqueada quando o código for finalizado e, portanto, deve
sempre seja bloqueado e desbloqueado usando uma construção try..finally. Se uma lista for deixada bloqueada, isso causará uma
impasse com outros threads tentando acessar a lista.
16.10 Indy
O Indy contém muitas classes adicionais que complementam o VCL para facilitar a segmentação. Essas classes
são realmente independentes da biblioteca principal do Indy e também são úteis em aplicativos que não são do Indy. Eles
existe no Indy porque o Indy foi projetado com threads em mente. Indy não apenas usa essas classes para
implementação do servidor, mas também os fornece para uso do desenvolvedor. Esta seção fornecerá uma breve
visão geral dessas classes.
16.11 TIdThread
O TIdThread é um descendente do TThread e adiciona recursos mais avançados, além de fornecer
recursos mais adequados para uso em servidores e também fornece suporte para pool e reutilização de threads.
Se você estiver familiarizado com o TThread da VCL, é muito importante observar que o TIdThread difere
acentuadamente em algumas áreas-chave. Com TThread, o método Execute é substituído por descendentes, mas com
TIdThread the Run método é substituído. Certifique-se de não substituir o Execute do TIdThread
https://translate.googleusercontent.com/translate_f 176/261
22/04/2020 Indy em Profundidade
Page 107
Tópicos 104
Para todos os descendentes de TIdThread, o método Run deve ser substituído. Quando o fio se torna
ativo, Executar será executado. A execução será chamada continuamente pelo TIdThread até que o thread tenha
encerrado. O uso disso pode não ser facilmente aparente para a maioria dos clientes, mas é especialmente
útil em quase todos os servidores e também em alguns clientes. Isso também é diferente do Execute do TThread
O método Execute é executado apenas uma vez e, quando sai, não é recuperado. Quando executar
sai, o encadeamento está concluído.
Também existem outras diferenças entre TIdThread e TThread, mas essas são as principais
diferenças, e Executar e Executar é o maior.
16.12 TIdThreadComponent
TIdThreadComponent é um componente que permite criar novos threads visualmente, simplesmente adicionando
evento em tempo de design. É basicamente apenas um encapsulamento visual do TIdThread, mas torna a criação de novas
tópicos realmente fáceis.
Para usar um TIdThreadComponent, adicione um ao seu formulário, defina o evento OnRun e defina o Active
propriedade. Um exemplo de TIdThreadComponent pode ser visto na demonstração TIdThreadComponent
disponível no Portal Indy .
16.13 TIdSync
O TThread possui um método Synchronize, mas não suporta a capacidade de passar parâmetros para
métodos sincronizados. O TIdSync permite sincronizações com a capacidade de passar parâmetros para o
métodos sincronizados também. O TIdSync também permite que valores de retorno sejam retornados do principal
fio.
https://translate.googleusercontent.com/translate_f 177/261
22/04/2020 Indy em Profundidade
16.14 TIdNotify
As sincronizações são boas quando o número de threads é pequeno. No entanto, para servidores ou aplicativos
com muitos threads, as sincronizações se tornam um gargalo e têm um impacto negativo drástico no
desempenho. Para resolver isso, notifcações podem ser usadas. Implementos TIdNotify da Indy
notificações. As notificações permitem a comunicação com o encadeamento primário, mas diferentemente das sincronizações
o encadeamento não será bloqueado até que a notificação seja processada. As notificações têm um desempenho muito semelhante
função à das sincronizações, mas sem o prejuízo no desempenho.
No entanto, as notificações têm algumas limitações. Uma é que um valor não pode ser retornado do principal
thread para o segmento de chamada, porque as notificações não suspendem o segmento de chamada.
16.15 TIdThreadSafe
TIdThreadSafe é uma classe base para implementar classes threadsafe. TIdThreadSafe nunca é usado
em si e é projetado apenas como uma classe base.
Page 108
O maior problema com os threads é simultaneidade. Como os threads são executados em paralelo, existe um
problema de simultaneidade ao acessar dados comuns. Ao usar threads em um aplicativo, os seguintes
problemas são comumente encontrados:
A execução de clientes Indy em threads traz os seguintes problemas de simultaneidade:
16.17 Gargalos
Muitos desenvolvedores criam aplicativos multiencadeados que funcionam bem quando o número de concorrentes
threads é pequeno, no entanto, os aplicativos atolam rapidamente quando o número de threads é
aumentado. Isso geralmente ocorre devido ao efeito gargalo. O efeito gargalo ocorre quando um determinado pedaço de
O código bloqueia a execução de outros threads e outros threads devem esperar nesse trecho de código para
completo. Não importa a velocidade do outro código, o ponto mais lento é o gargalo. Ou seja, o código pode
só seja tão rápido quanto a parte mais lenta.
Muitos desenvolvedores, em vez de procurar gargalos, gastam seu tempo melhorando partes do código que
suspeito não é "rápido o suficiente", mas quando comparado aos gargalos existentes, é insignificante se houver
efeito.
Geralmente, eliminar um gargalo obterá um aumento líquido na velocidade mais rápido que dezenas, se não
centenas de outras otimizações. Por isso, concentre-se nos gargalos primeiro. Então e só então,
outro código deve ser analisado para possível otimização.
Geralmente, uma seção crítica é usada para proteger vários recursos. Isso recebe os recursos A, B e C,
uma seção crítica é usada para protegê-los coletivamente, mas cada recurso é independente. o
surge um problema, enquanto B está em uso, A e C também estão bloqueados. Seções críticas são bastante
leve e uma seção crítica dedicada deve ser usada para cada recurso.
https://translate.googleusercontent.com/translate_f 179/261
22/04/2020 Indy em Profundidade
Seções críticas também às vezes bloqueiam muito código. A quantidade de código entre o Enter e
Os métodos de licença de uma seção crítica devem ser mantidos em um mínimo absoluto e, na maioria dos casos, múltiplos
seções críticas usadas, se possível.
16.17.2 TMREWS
O TMREWS pode fornecer um aumento significativo no desempenho em seções críticas, se a maioria dos acessos for
limitado à leitura e apenas algum acesso requer escrita. No entanto, a classe TMREWS é mais pesada
peso do que uma seção crítica e requer mais código para obter um bloqueio. Para pedaços muito pequenos de código,
mesmo se a escrita for mínima, geralmente uma seção crítica terá um desempenho melhor que um TMREWS.
Page 109
Tópicos 106
16.17.3 Sincronizações
Sincronizações são geralmente usadas para executar atualizações da interface do usuário.
O problema com a sincronização é que o encadeamento de chamada fica em pausa até que a sincronização seja concluída.
completo. Como o encadeamento principal processa todas as sincronizações, apenas um pode ser processado por vez
e assim eles são serializados. Isso faz com que todas as sincronizações globalmente se tornem uma grande
gargalo.
Os ganhos de desempenho obtidos com o multiencadeamento de um aplicativo podem ser rapidamente perdidos por atrasos causados por
atualizações da interface do usuário. Em muitos casos, isso fará com que um aplicativo multiencadeado execute mais lentamente
do que sua versão com rosca única.
Considerações especiais devem ser tomadas com as implementações do servidor. Um servidor é um servidor e seu principal
responsabilidade é para com seus clientes. A interface do usuário é secundária a sua função. Assim é perfeitamente
aceitável tornar a interface do usuário um aplicativo separado, que é um cliente especial para o
servidor. Outra opção é usar técnicas como notificações ou atualizações em lote. Ambos estes
fazer com que a interface do usuário fique um pouco atrasada, mas é muito melhor ter uma interface do usuário
um segundo atrasado do que para 200 clientes cada um atrasado 1 segundo. Com servidores, os clientes são o rei.
https://translate.googleusercontent.com/translate_f 181/261
22/04/2020 Indy em Profundidade
(C) 2003 Atozed Computer Software Ltd.
Page 110
Seção
https://translate.googleusercontent.com/translate_f 182/261
22/04/2020 Indy em Profundidade
XVII
Servidores
Page 111
Servidores 108
17 Servidores
https://translate.googleusercontent.com/translate_f 183/261
22/04/2020 Indy em Profundidade
O Indy possui uma variedade de modelos de servidor, dependendo de suas necessidades e do protocolo usado. Os próximos
As seções fornecerão uma visão geral dos componentes básicos do servidor Indy.
https://translate.googleusercontent.com/translate_f 184/261
22/04/2020 Indy em Profundidade
Page 112
17.1.1 TIdTCPServer
O servidor Indy mais proeminente é o TIdTCPServer.
https://translate.googleusercontent.com/translate_f 185/261
22/04/2020 Indy em Profundidade
Os servidores Indy são projetados em torno de threads e operam de maneira semelhante à forma como os servidores Unix
operar. Aplicativos Unix geralmente fazem interface diretamente com a pilha com pouca ou nenhuma camada de abstração.
Indy isola o programador da pilha usando um alto nível de abstração e internamente
implementa muitos detalhes que podem ser automáticos e transparentes.
Normalmente, os servidores Unix têm um ou mais processos de ouvinte que observam solicitações de entrada de
clientes. Para cada solicitação de cliente aceita pelo processo do ouvinte, o servidor cria um novo processo para
lidar com cada conexão do cliente. O manuseio de várias conexões de clientes dessa maneira é muito fácil, pois
cada processo lida com apenas um cliente. O processo também é executado em seu próprio contexto de segurança, que pode
ser definido pelo ouvinte ou pelo próprio processo, com base em credenciais, autenticação ou outros meios.
Os servidores Indy operam de maneira muito semelhante. Windows diferente do Unix não funciona bem, mas o Windows
executa rosqueamento muito bem. Os servidores Indy alocam um encadeamento para cada conexão do cliente em vez de
um processo completo como o Unix. Isso fornece quase todas as vantagens dos processos, com nenhuma
das desvantagens
Com um servidor ocupado, centenas ou até milhares de threads podem ser facilmente necessários. Existe um
equívoco comum de que centenas de threads matarão seu sistema. Esta é uma crença falsa.
O número de threads que seu sistema está executando agora pode surpreendê-lo. Com apenas um mínimo
serviços iniciados e os seguintes aplicativos em execução:
https://translate.googleusercontent.com/translate_f 186/261
22/04/2020 Indy em Profundidade
Page 113
Servidores 110
https://translate.googleusercontent.com/translate_f 187/261
22/04/2020 Indy em Profundidade
Aqui está uma captura de tela do meu sistema que possui 333 threads atualmente criados:
Page 114
https://translate.googleusercontent.com/translate_f 188/261
22/04/2020 Indy em Profundidade
Mesmo com 513 threads, você pode ver que a utilização da CPU é de apenas 1%. Um IIS muito usado (Microsoft
Internet Information Server) criará centenas ou milhares mais threads. Este teste foi realizado
em um Pentium III 750 MHz com 256 MB de RAM.
Na maioria dos servidores, os threads passam a maior parte do tempo aguardando dados. Enquanto aguarda o bloqueio de chamadas,
o encadeamento ficará inativo. Assim, em um servidor com 500 threads, apenas 25 podem estar ativos ao mesmo tempo.
Em aplicações de soquete, existem outras restrições ditadas pelo componente mais lento. Na rede
aplicações, a placa de rede é tipicamente um dos componentes mais lentos e, portanto, nada pode exceder
a capacidade da placa de rede. Mesmo uma placa de rede rápida é muitos fatores mais lenta que uma CPU e, em
a maioria dos casos será o gargalo, mesmo se totalmente utilizada.
https://translate.googleusercontent.com/translate_f 189/261
22/04/2020 Indy em Profundidade
Realisticamente, o sistema médio começará a ver problemas com um processo quando o processo criar
mais de 1.000 threads devido a problemas de memória. O tamanho da pilha dos encadeamentos pode ser reduzido para
aumentar o número de threads, no entanto, neste momento, outras alternativas devem ser investigadas.
A maioria dos servidores requer apenas algumas centenas de threads, no máximo. No entanto, servidores de volume muito alto ou
servidores com muito tráfego baixo, mas clientes conectados, como um servidor de bate-papo de alto volume,
precisa ser implementado de uma maneira diferente. Esses servidores usando Indy criariam vários
mil threads.
Page 115
Servidores 112
Também é importante entender que o número de clientes não é necessariamente o mesmo que o concorrente
tópicos. Enquanto cada cliente recebe um thread individual, um thread é alocado apenas enquanto o cliente
está conectado. Muitos servidores atendem a conexões de curta duração, como um servidor HTTP. HTTP
as conexões para páginas da web geralmente duram apenas um segundo ou menos, especialmente se o proxy ou o cache estiver
usava. Assumindo 1 segundo por conexão e apenas 500 threads, isso permitiria 30.000 clientes
por hora.
O Indy 10 atende a essas necessidades, permitindo outros modelos, além da segmentação de servidores. Indy 10
é limitado apenas pela memória disponível para alocar soquetes.
Há duas maneiras de criar servidores TCP, com manipuladores de comando e o evento OnExecute.
Os manipuladores de comando facilitam muito a criação de servidores, mas não adaptam todas as situações.
Manipuladores de comando são adequados para protocolos que trocam comandos em formato de texto, mas não são adequados
https://translate.googleusercontent.com/translate_f 190/261
22/04/2020 Indy em Profundidade
para protocolos que possuem uma estrutura de comando binária ou nenhuma estrutura de comando. A maioria dos protocolos é de texto
manipuladores baseados e de comando podem ser usados. Manipuladores de comando são completamente opcionais. Se não for usado,
Os servidores Indy ainda suportam os métodos antigos de uso. Os manipuladores de comando são abordados com mais detalhes no
seção de manipuladores de comando .
Alguns protocolos são binários ou não possuem estrutura de comando e não são adequados para manipuladores de comando.
Para esses servidores, o evento OnExecute deve ser usado. OnExecute ocorre repetidamente, desde que o
a conexão está ativa e passa a conexão como argumento. Um servidor muito simples implementado
O uso do OnExecute pode ficar assim:
Não é necessário verificar se há uma conexão válida, pois o Indy faz isso automaticamente. Também não há
precisa executar qualquer loop, pois o Indy também fará isso por você. Ele chama o evento repetidamente até que haja
não é mais uma conexão. Isso pode ser causado por uma desconexão explícita, como mostrado acima, por um
erro de rede ou pelo cliente desconectando. De fato, nenhum loop deve ser feito, pois isso pode interferir
com a detecção de desconexão da Indy. Se o loop deve ser realizado internamente neste evento, deve-se ter cuidado especial
tomar para permitir que essas exceções borbulhem para Indy para que ele possa lidar com elas também.
O Indy 9.0 contém um novo recurso chamado manipuladores de comando. Manipuladores de comando são um novo conceito
usado no TIdTCPServer que permite que o servidor execute a análise e o processamento de comandos para você.
Os manipuladores de comando são uma espécie de "gerenciamento visual do servidor" e são apenas um pequeno pico
no futuro dos servidores Indy.
https://translate.googleusercontent.com/translate_f 191/261
22/04/2020 Indy em Profundidade
Page 116
Para cada comando que você deseja que o servidor manipule, um manipulador de comandos é criado. Imagine
manipuladores de comando como listas de ações para servidores. O manipulador de comandos contém propriedades que informam
como analisar o comando, incluindo como analisar parâmetros, o próprio comando, algumas ações que
possivelmente, pode executar a si próprio e respostas automáticas opcionais. Em alguns casos, usando apenas as propriedades, você
pode criar um comando totalmente funcional sem precisar escrever nenhum código. Cada manipulador de comandos possui um
evento OnCommand exclusivo. Quando o evento é chamado, não há necessidade de determinar qual comando
foi solicitado, pois cada evento é exclusivo para um manipulador de comandos. Além disso, o comando
O manipulador já executou ações opcionais para você e analisou os parâmetros para seu uso.
Aqui está uma demonstração muito básica de como usar manipuladores de comando. Primeiro, devemos definir os dois comandos:
SAIR e DATA. Para fazer isso, dois manipuladores de comando são criados em tempo de design, como mostrado aqui:
Para cmdhQuit, a propriedade desconectar está configurada como true. Para cmdhDate, o evento OnCommand é definido
como mostrado aqui:
Este é o código completo para a versão do manipulador de comandos. Todos os outros detalhes foram especificados por
definindo propriedades dos manipuladores de comando.
Os manipuladores de comando são abordados com mais detalhes na seção manipuladores de comando .
17.1.2 TIdUDPServer
Como o UDP não possui conexão (definição), o TIdUDPServer opera de maneira diferente do TIdTCPServer.
O TIdUDPServer não possui modos semelhantes ao TIdSimpleServer, mas como o UDP é
sem conexão, o TIdUDPClient possui métodos de escuta de uso único.
O TIdUDPServer quando ativo cria um encadeamento de escuta para escutar pacotes UDP de entrada. Para cada
Pacote UDP recebido, o TIdUDPServer disparará o evento OnUDPRead no thread principal ou no diretório
https://translate.googleusercontent.com/translate_f 192/261
22/04/2020 Indy em Profundidade
Quando ThreadedEvent for false, o evento OnUDPRead será disparado no contexto do programa principal
fio. Quando ThreadedEvent for true, o evento OnUDPRead é acionado no contexto do ouvinte
fio.
Quando ThreadedEvent for verdadeiro ou falso, sua execução bloqueará o recebimento de mais mensagens.
Por isso, o processamento do evento OnUDPRead deve ser rápido.
17.1.3 TIdSimpleServer
TIdSimpleServer é para criar servidores de uso único. O TIdSimpleServer destina-se a atender a um único
conexão de cada vez. Embora possa atender a outra solicitação após a conclusão de uma solicitação, é
normalmente usado para solicitações de uso único.
TIdSimpleServer não gerará nenhum ouvinte ou segmentos de conexão secundários. Toda a sua funcionalidade
ocorre de dentro do segmento que é usado.
O componente do cliente TIdFTP utiliza TIdSimpleServer. Quando o FTP realiza uma transferência de arquivos, um secundário
A conexão TCP é aberta para transferir os dados e fechada quando os dados são transferidos. este
A conexão é chamada de "canal de dados" e é exclusiva para cada transferência de arquivo.
Page 117
Servidores 114
Isso pode parecer um pouco confuso no começo, como o evento pode aparecer como parte do formulário, mas executar
de dentro de um thread. No entanto, foi construído dessa maneira intencionalmente para que os eventos pudessem ser
criado em tempo de design, como qualquer outro evento, sem a necessidade de criar classes personalizadas e
fornecer substituições.
Se os componentes descendentes estiverem sendo criados, as substituições também estarão disponíveis. No entanto, para a construção
aplicativos, o modelo de evento é muito mais fácil de usar.
Cada cliente recebe seu próprio encadeamento. Usando esse encadeamento, os eventos do servidor TCP (que são
partes do formulário ou módulo de dados quando criadas) são chamadas a partir desses threads. Isso significa que um
Um único evento pode ser chamado várias vezes a partir de vários threads. Tais eventos recebem um AThread
argumento que especifica o segmento que está chamando o evento.
https://translate.googleusercontent.com/translate_f 194/261
22/04/2020 Indy em Profundidade
17.3.1 OnExecute
OnExecute refere-se ao evento OnExecute do TIdTCPServer. Ao implementar um servidor usando este
No modelo, o OnExecute deve ser definido ou o método DoExecute deve ser substituído.
Page 118
Depois que um cliente se conectar a um servidor, o OnExecute será acionado. Se nenhum OnExecute estiver definido, um
exceção será gerada. O evento OnExecute se disparado de dentro de um loop, desde que o cliente esteja
conectado. Este é um detalhe muito importante e, por causa disso, os desenvolvedores devem ser cautelosos em:
https://translate.googleusercontent.com/translate_f 195/261
22/04/2020 Indy em Profundidade
Se todas essas condições e outras verificações forem verdadeiras, o OnExecute será chamado novamente. Por causa disso,
Os desenvolvedores nunca devem construir seu próprio código de loop dentro do OnExecute, que tenta
replicar isso, pois irá interferir com Indy.
https://translate.googleusercontent.com/translate_f 196/261
22/04/2020 Indy em Profundidade
Page 119
Servidores 116
https://translate.googleusercontent.com/translate_f 197/261
22/04/2020 Indy em Profundidade
Os manipuladores de comando estão de uma maneira, listas de ações para servidores. Manipuladores de comando trabalham de tal maneira
moda que você define um manipulador de comando para cada comando e, em seguida, usando esse manipulador de comando
defina o comportamento e as respostas para esse comando específico. Quando um comando é recebido de
o cliente, o servidor o analisa automaticamente e o passa para o manipulador de comandos apropriado.
Os manipuladores de comando não têm apenas propriedades para personalizar seu comportamento, mas também métodos e
eventos também.
Os manipuladores de comando funcionam apenas com comando e resposta (conversacional) TCP baseados em texto
protocolos. No entanto, isso cobre cerca de 95% dos servidores em uso comum atualmente. Enquanto
Os manipuladores de comando podem lidar com dados binários, eles podem lidar apenas com comandos de texto. Há alguns
protocolos que usam comandos binários. Para protocolos que usam comandos binários ou comandos de texto que
não são conversacionais, a implementação dos Manipuladores de Comando também preserva
compatibilidade e permite que os servidores sejam implementados sem eles.
17.4.1 Implementação
TCPServer contém uma propriedade chamada CommandHandlers, que é uma coleção de comandos
manipuladores. Os manipuladores de comando geralmente são criados em tempo de design, no entanto, para a implementação do protocolo
descendentes, eles também podem ser criados em tempo de execução. Se os manipuladores de comando forem criados no tempo de execução, eles
deve ser criado substituindo o método InitializeCommandHandlers. Isso garantirá que eles
são criados apenas um tempo de execução. Se eles forem criados no construtor, serão criados sempre que o
O TCPServer é transmitido e, quando transmitido, eles serão salvos. Em breve haverá muitos
Page 120
cópias de cada manipulador de comandos. A inicialização é chamada depois que o TCPServer é ativado pela primeira vez.
O manipulador é acionado antes de cada manipulador de comandos ser processado. OnNoCommandHandler é acionado se não houver
Foi encontrado um manipulador de comandos que corresponde ao comando.
Se CommandHandlersEnabled for true e existirem manipuladores de comando, o processamento do manipulador de comando será
realizada. Caso contrário, o evento OnExecute é chamado if assignd. OnExecute não é chamado se o comando
O processamento do manipulador é realizado.
â € ¢ Ajuda - Exiba uma lista de comandos suportados e ajuda básica em cada um.
â € ¢ DateTime <formato> - Retorna a data e / ou hora atuais usando o formato especificado. Se nenhum formato for
especificado o formato aaaa-mm-dd hh: nn: ss será usado.
â € ¢ Sair - encerre a sessão e desconecte-se.
Esta é uma implementação muito básica, mas funcionará muito bem para fins de demonstração. Você pode
deseja expandi-lo para brincar ainda mais com os recursos dos manipuladores de comando.
Isso criará o aplicativo base. Ainda não faz nada, pois não há eventos ou comandos
manipuladores foram criados.
https://translate.googleusercontent.com/translate_f 199/261
22/04/2020 Indy em Profundidade
Page 121
Servidores 118
Está vazio porque nenhum manipulador de comando foi criado. Para criar um manipulador de comandos
clique com o botão direito na área branca e selecione adicionar ou selecione o primeiro botão na barra de ferramentas. Depois de fazer isso, um
O manipulador de comandos será listado no editor de propriedades, como mostrado aqui:
https://translate.googleusercontent.com/translate_f 200/261
22/04/2020 Indy em Profundidade
Para editar o manipulador de comandos, este editor de propriedades é usado para selecionar o manipulador de comandos e, em seguida, o
O inspetor de objetos é usado para editar suas propriedades e eventos. Editar manipuladores de comando é o mesmo que
editar campos de um conjunto de dados ou colunas de um DBGrid. Se o inspetor de objetos não estiver visível, pressione o botão F11
para exibi-lo.
O inspetor de objetos será semelhante a este. Este aqui já possui algumas propriedades modificadas
dos padrões para implementar o comando QUIT e será abordado a seguir.
https://translate.googleusercontent.com/translate_f 201/261
22/04/2020 Indy em Profundidade
Page 122
Passo a passo, aqui estão as propriedades que foram modificadas para implementar o comando QUIT:
1. Command = Quit - Este é o comando que o servidor usa para corresponder à entrada do cliente e
determine qual manipulador de comando manipulará o comando. O comando não diferencia maiúsculas de minúsculas.
2. Desconectar = Verdadeiro - Isso informa ao servidor para desconectar o cliente após a execução deste comando.
processado.
3. Name = cmdhQuit - Isso não afeta o comportamento do manipulador de comandos, mas o torna
mais fácil de identificar no código, se necessário. Esta etapa é opcional.
4. ReplyNormal.NumericCode = 200 - Normalmente, os comandos são respondidos com um código numérico de 3 dígitos
e texto opcional. Isso informa ao manipulador de comandos para responder com 200 mais qualquer texto encontrado em
ReplyNormal.Text se nenhum erro ocorrer durante o processamento do comando.
5. ReplyNormal.Text = Adeus - Este texto também é enviado com ReplyNormal.NumericCode.
https://translate.googleusercontent.com/translate_f 202/261
22/04/2020 Indy em Profundidade
Cumprimento
É prática comum que os servidores forneçam uma resposta na conexão antes que o servidor receba
comandos do cliente. Uma resposta típica que indica que o servidor está pronto é 200 e configurá-lo
para zero, permitirá o envio da saudação.
ReplyExceptionCode
Se ocorrer alguma exceção não tratada durante o processamento de um comando, esse número será usado para
construa uma resposta para o cliente se seu valor for diferente de zero. 500 é uma resposta típica para desconhecido interno
erros. Para a parte do texto da resposta, o texto da exceção será enviado.
Page 123
Servidores 120
Desconhecido
Se nenhum manipulador de comando correspondente for encontrado para um comando emitido por um cliente, o TIdTCPServer
A propriedade ReplyUnknownCommand é usada para retornar um erro ao cliente. 400 é uma resposta comum
por erros internos.
Outras propriedades
Existem outras propriedades e até eventos do TIdTCPServer para implementar comportamentos adicionais
relacionados aos manipuladores de comando, mas os listados aqui são os que devem ser implementados como um
mínimo.
1. Execute o aplicativo.
2. Na caixa de diálogo Iniciar: Executar, digite: telnet 127.0.0.1 6000 e pressione OK. Isso instrui o telnet a
conecte-se ao computador na porta 6000, que é a porta na qual a demonstração está escutando.
3. O servidor deve responder com 200 Hello, que é a saudação que foi definida na Saudação
propriedade de TIdTCPServer anteriormente.
4. O Telnet exibirá um sinal de intercalação. Isso significa que o servidor está pronto e aguardando a entrada (ou seja, um
comando).
5. Digite HELP e pressione enter. O servidor responde com "400 Comando desconhecido". Isto é
porque nenhum comando HELP foi implementado ainda e o "400 Comando Desconhecido" foi
o que foi definido na propriedade ReplyUnknown.
6. Digite QUIT . O servidor responde com "200 adeus" e desconecta o cliente.
Parabéns! Você acabou de criar um servidor usando manipuladores de comando. A próxima seção progredirá
com a implementação dos outros dois comandos HELP e DATETIME, que têm comportamentos diferentes
e precisa de QUIT.
Você deve estar familiarizado com todas essas etapas, pois elas são semelhantes às implementadas no QUIT. o
A propriedade adicional usada para implementar a forma textual da resposta é a Resposta
propriedade que é uma lista de cadeias. Se a resposta contiver texto, ele será enviado ao cliente após ReplyNormal
é enviado. Para implementação do comando HELP, use o editor de propriedades da lista de cadeias para o Response
propriedade e insira:
Page 124
Ajuda - Exiba uma lista de comandos suportados e ajuda básica em cada um.
DateTime <formato> - Retorna a data e / ou hora atuais usando o especificado
formato.
Se nenhum formato for especificado, o formato aaaa-mm-dd hh: nn: ss será usado.
Sair - encerre a sessão e desconecte.
Agora, se você se conectar ao servidor e enviar o comando HELP, o servidor responderá da seguinte maneira:
200 Hello
Socorro
200 Ajuda a seguir
Ajuda - Exiba uma lista de comandos suportados e ajuda básica em cada um.
DateTime <formato> - Retorna a data e / ou hora atuais usando o especificado
formato.
Se nenhum formato for especificado, o formato aaaa-mm-dd hh: nn: ss será usado.
Sair - encerre a sessão e desconecte.
.
AJUDA, pois requer alguma funcionalidade personalizada que não pode ser criada apenas usando propriedades.
Na implementação de DATETIME, um evento será usado para implementar esse comportamento personalizado.
Primeiro, crie o manipulador de comandos base usando as etapas que você já conhece:
Desta vez, um ReplyNormal.Text não foi definido, o evento o definirá para cada solicitação. Para
Para definir o evento, use o Inspetor de objetos enquanto o manipulador de comandos DATETIME está selecionado.
Alterne para a guia events e crie um evento OnCommand. O Delphi criará um shell de evento como
mostrado a seguir:
fim ;
Antes do evento ser chamado, o Indy criará uma instância do comando e inicializará suas propriedades
com base no manipulador de comandos. Você pode usar o comando para alterar as propriedades de seus
padrões, chame métodos para instruir o comando a executar tarefas ou acesse sua conexão
propriedade para interagir diretamente com a conexão.
Este protocolo define DATETIME como aceitando um parâmetro opcional que especifica o formato da data
e hora de ser devolvido. O comando tem suporte para isso também na propriedade Params, que
é uma lista de cadeias. Quando um comando é recebido do cliente, se o manipulador de comandos
A propriedade ParseParams é True (True é o padrão) Indy usará a propriedade CmdDelimeter
(cujo padrão é # 32 ou espaço) para analisar o comando no comando e em seus parâmetros.
https://translate.googleusercontent.com/translate_f 206/261
22/04/2020 Indy em Profundidade
Page 125
Servidores 122
DATETIME hhnnss
Observe o uso de ASender.Reply.Text.Text. O texto é necessário duas vezes porque a propriedade Text do
O comando é uma lista de cadeias de caracteres e estamos acessando TStrings.Text além disso. Como é uma lista de cadeias,
outros métodos ou propriedades como Adicionar, Excluir etc. também podem ser usados. O texto é usado aqui como
O ASender.Reply.Text pode ser pré-inicializado em alguns casos, e o uso do ASender.Reply.Text.Text
sobrescreva qualquer texto preexistente.
Se a demonstração for testada novamente usando telnet, ela produzirá resultados semelhantes aos seguintes:
200 Hello
data hora
200 2002-08-26 18:48:06
Em alguns casos, os parâmetros não podem ser usados. DATETIME é um deles. Considere se o usuário envia isso como
https://translate.googleusercontent.com/translate_f 207/261
22/04/2020 Indy em Profundidade
um comando:
DATETIME mm dd aa
Nesse caso, Params.Count seria 3 e o evento falharia e retornaria apenas o valor por meses
(milímetros). Nos casos em que o parâmetro incorporou delimitadores, a propriedade UnparsedParams do
comando deve ser usado em seu lugar. Opcionalmente, a propriedade ParseParams pode ser definida como False.
UnparsedParams conterá os dados independentemente do valor de ParseParams, mas configurá-lo como false
aumentará a eficiência dizendo ao Indy que não há necessidade de analisar os parâmetros nos Params
propriedade.
Page 126
17.4.9 Conclusão
Os manipuladores de comando são muito flexíveis e contêm muito mais propriedades e métodos do que os cobertos
aqui. Esta é apenas uma introdução aos manipuladores de comando e seus recursos. Espero que tenha
foi coberto para despertar o seu interesse e começar.
Também existem planos especiais para versões futuras do Indy para tornar os manipuladores de comando ainda mais visuais
https://translate.googleusercontent.com/translate_f 208/261
22/04/2020 Indy em Profundidade
na fase de design.
O uso de gerenciadores de encadeamentos é opcional. Se você não especificar um gerenciador de encadeamentos para usar, definindo
Propriedade ThreadManager de um componente que oferece suporte ao gerenciamento de threads (como TIdTCPServer)
Indy criará e destruirá implicitamente uma instância do gerenciador de threads padrão,
TIdThreadMgrDefault .
17.7.1 TIdThreadMgrDefault
O gerenciamento de threads padrão no Indy é muito simples e básico. Cada vez que um encadeamento é necessário, um é
criado. Quando não é mais necessário, é destruído. Para a maioria dos servidores, isso é aceitável e, a menos que
você justificou a necessidade de um conjunto de encadeamentos, deve usar o gerenciamento de encadeamentos padrão. Na maioria
servidores, a diferença de desempenho será insignificante ou nenhuma.
Ele também tem a vantagem adicional de garantir que cada thread seja "limpo". Os threads geralmente alocam
memória ou outros objetos. Esses objetos geralmente são limpos automaticamente quando a linha é
destruído. Assim, o uso do gerenciamento de encadeamentos padrão ajudará a garantir que toda a memória seja liberada também
como limpo. Quando o pool de encadeamentos for usado, se você armazenar dados associados ao encadeamento, deverá ser
https://translate.googleusercontent.com/translate_f 209/261
22/04/2020 Indy em Profundidade
certifique-se de limpá-lo antes que a linha seja reutilizada novamente. Não fazer isso pode fornecer aos usuários informações sensíveis
informações de um usuário anterior. Nenhuma precaução é necessária com o gerente padrão, pois
o encadeamento e os dados associados são destruídos a cada vez.
Page 127
Servidores 124
Com o pool de threads, os threads são reciclados e também pré-alocados. Em um pool de threads, os threads são criados
antes de serem necessários e mantidos inativos em uma piscina. Quando um encadeamento é necessário, um é retirado do
piscina e ativado. Se forem necessários mais threads do que os disponíveis no pool, mais threads serão
criado. Quando um encadeamento não é mais necessário, em vez de ser destruído, é desativado e
reposicionado no pool para que possa ser reutilizado mais tarde, quando necessário.
A criação e destruição de encadeamentos podem consumir muitos recursos. Isto é especialmente evidente com
servidores que possuem conexões de curta duração. Esses servidores criam um encadeamento e o utilizam por um período muito breve e
então destrua-o. Isso causa uma frequência muito alta de criação e destruição de threads. A
Um exemplo disso é um servidor de tempo, ou mesmo e web. Uma única solicitação é enviada e uma resposta simples
devolvida. Ao usar um navegador para navegar em um site, centenas de conexões e desconexões para
o servidor pode ocorrer.
O pool de threads pode aliviar essas situações. Em vez de criar e destruir threads sob demanda,
https://translate.googleusercontent.com/translate_f 210/261
22/04/2020 Indy em Profundidade
os encadeamentos são emprestados de uma lista de lista inativa, mas já criada (pool). Quando um encadeamento não é mais
necessário, é depositado de volta na piscina em vez de ser destruído. Enquanto os threads estão no pool
eles são marcados como inativos e, portanto, não consomem ciclos da CPU. Para uma melhoria adicional, o tamanho de
o pool pode ser ajustado dinamicamente para atender às necessidades atuais do sistema.
Indy suporta pool de threads. O agrupamento de threads no Indy pode ser alcançado através do uso do
Componente TIdThreadMgrPool.
https://translate.googleusercontent.com/translate_f 211/261
22/04/2020 Indy em Profundidade
Page 128
Seção
https://translate.googleusercontent.com/translate_f
XVIII 212/261
22/04/2020 Indy em Profundidade
Page 129
SSL significa Secure Socket Layer e é o método de criptografia aceito para criptografar dados no
Internet. O SSL é geralmente usado com tráfego HTTP (Web) e conhecido como HTTP seguro
(HTTPS). O SSL, no entanto, não se limita ao HTTP e pode ser usado com qualquer um dos protocolos TCP / IP.
https://translate.googleusercontent.com/translate_f 213/261
22/04/2020 Indy em Profundidade
No Indy
moda, para
mas usar SSL,
a única você deve
biblioteca primeiro instalar
SSL atualmente as DLLs éSSL
implementada apropriadas.
o OpenSSL. O suporteOpenSSL
A biblioteca SSL da Indy
estáédisponível
feito em ambiente aberto
como um conjunto de DLLs e está disponível para download separadamente na distribuição principal do Indy.
A restrição se aplicava apenas a distribuições eletrônicas e não se aplicava a todas as formas de fonte impressa
código. A restrição também se aplicava apenas à exportação, não à importação.
Muitas dessas questões foram resolvidas desde então e alguns governos se iluminaram.
No entanto, muitas restrições de exportação ainda estão em vigor e variam de país para país. Por causa disso,
todo o trabalho SSL da Indy é realizado na Eslovênia e toda a tecnologia de criptografia SSL relacionada à Indy é distribuída
da Eslovênia. A Eslovênia não tem restrições à exportação de criptografia.
Além da exportação de criptografia, alguns países têm restrições de uso ou mesmo posse
de tecnologias de criptografia. Você deve verificar as leis de seu país antes de implementar ou usar o SSL.
Países como China, Iraque e outros têm penas severas e até mortais por possuírem
essa tecnologia.
Observe que, para que uma sessão HTTPS seja estabelecida, o servidor da Web que responderá ao
A solicitação deve suportar SSL e ter certificados de criptografia instalados. O cliente HTTP Indy também faz
não verificar automaticamente os certificados do servidor, é de sua responsabilidade.
https://translate.googleusercontent.com/translate_f 214/261
22/04/2020 Indy em Profundidade
O SSL pode ser facilmente implementado com qualquer cliente TCP Indy pelo uso de um IOHandler SSL. Normalmente
a criptografia deve ser implementada usando um Intercept em vez de um IOHandler. SSL é implementado em
Indy usando um IOHandler em vez de um Intercept porque as bibliotecas SSL realmente executam o
comunicações em si. Os dados são retornados e aceitos de forma não criptografada diretamente do
Bibliotecas SSL.
Page 130
Para fazer um cliente TCP Indy usar SSL, adicione um TIdSSLIOHandlerSocket ao formulário a partir do
Guia Indy Misc. Agora defina a propriedade IOHandler do seu cliente TCP como TIdSSLIOHandlerSocket. Para
suporte SSL básico, isso é tudo o que é necessário. O TIdSSLIOHandlerSocket possui recursos adicionais
propriedades para especificar certificados do lado do cliente e outras opções SSL mais avançadas.
Certificados geralmente são obtidos de uma autoridade de certificação confiável. Você pode fazer o seu próprio
certificados e seja sua própria autoridade confiável, mas nenhum dos navegadores confiará em seus certificados e
os navegadores exibirão um aviso ao se conectar ao seu servidor. Se você deseja implantar no
Internet, você deve obter um certificado de uma autoridade de certificação em que os navegadores padrão confiam.
https://translate.googleusercontent.com/translate_f 215/261
22/04/2020 Indy em Profundidade
A Verisign é a única autoridade confiável por todos os navegadores. O Thawte também pode ser usado, mas nem todos os navegadores
confie no Thawte por padrão.
Se seus clientes estiverem sob seu controle, como em uma intranet ou extranet, você poderá optar por ser o seu
própria autoridade confiável. Para evitar a caixa de diálogo de aviso, no entanto, você deve instalar seu certificado em cada
navegador que se conectará ao seu servidor. Isso permite que o navegador considere as assinaturas em seu
certificados como sendo de uma autoridade confiável.
Observe que isso se aplica apenas a servidores HTTP, mas o SSL não se limita ao HTTP. Você pode implementar o SSL se
você está implementando o cliente e o servidor e tem controle total sobre regras e associações de confiança.
Este procedimento pressupõe que você já recebeu seu par de chaves e certificados de alguns
Autoridade de Certificação (como Verisign ou Thawte) e que você os tenha instalado no Microsoft Internet
Explorer no repositório de certificados pessoais.
Page 131
https://translate.googleusercontent.com/translate_f 216/261
22/04/2020 Indy em Profundidade
openssl.exe pkcs12 - dentro de <seu arquivo> .pfx - fora de <seu arquivo> .pem
Openssl.exe solicitará uma senha. Digite se você usou um ou deixe em branco se não
especifique um. Também solicitará uma nova senha para o arquivo .pem. Isso é opcional, mas se você
proteja-o com uma senha, certifique-se de criar um evento OnGetPassword na interceptação SSL.
18.4.4 Key.pem
Crie key.pem com o bloco de notas e cole tudo entre e incluindo estas duas instruções:
18.4.5 Cert.pem
Crie cert.pem com o bloco de notas e cole tudo entre e incluindo estas duas instruções:
18.4.6 Root.pem
O arquivo final que Indy exige é o arquivo de certificado da Autoridade de Certificação. Você pode obter isso no
Internet Explorer na caixa de diálogo Autoridade de Certificação Raiz Confiável. Selecione a Autoridade que emitiu seu
certificado e exporte-o no formato Base64 (cer). Esse formato também é o mesmo que o formato PEM, portanto, após
exportar simplesmente renomeie o arquivo para root.pem
https://translate.googleusercontent.com/translate_f 217/261
22/04/2020 Indy em Profundidade
Page 132
https://translate.googleusercontent.com/translate_f 218/261
22/04/2020 Indy em Profundidade
Seção
XIX
Visão geral do Indy 10
https://translate.googleusercontent.com/translate_f 219/261
22/04/2020 Indy em Profundidade
Page 133
O Indy 10 ainda está em desenvolvimento. A consistência do código atual pode ser comparada à do código sujo
óleo de motor. Dentro de algumas semanas, deve ser mais sólido e ter a consistência de um bom creme. Assim, qualquer
as informações abordadas aqui estão sujeitas a alterações antes do lançamento final do Indy 10. A informação
apresentado aqui é baseado no código atual, nas metas de design e nas direções projetadas.
O Indy 10 contém muitos recursos novos, principalmente os relacionados à parte referida como núcleo. Indy 10
O núcleo foi ainda mais abstraído para facilitar a expansão. O núcleo do Indy 10 também contém muitos novos
recursos e grandes aprimoramentos de desempenho.
19.1 Alterações
https://translate.googleusercontent.com/translate_f 220/261
22/04/2020 Indy em Profundidade
Page 134
https://translate.googleusercontent.com/translate_f 221/261
22/04/2020 Indy em Profundidade
O núcleo contém todas as partes principais, componentes do cliente base e componentes do servidor base. Testemunho
não implementa nenhum protocolo de nível superior.
O pacote de protocolos usa o núcleo e implementa protocolos de nível superior, como POP3, SMTP e
HTTP.
Isso permite que a equipe da Pit Indy se concentre melhor em partes específicas. Também beneficia usuários que estão
implementar protocolos personalizados e pode não precisar do pacote de protocolos.
O Indy 10 continua a incluir suporte ao OpenSSL, no entanto, os recursos SSL do Indy são
completamente plugável no nível do núcleo e do protocolo para outras implementações.
O SSL e outros métodos de criptografia estão sendo desenvolvidos tanto pelo SecureBlackbox de terceiros quanto pelo
StreamSec.
â € ¢ POP3
â € ¢ SMTP
â € ¢ FTP
â € ¢ NNTP
O código de suporte SASL foi redesenhado para ser usado com POP3 e IMAP4. Indy 10 agora
suporta SASL anônimo, SASL comum, OTP (sistema de senha de uso único) SASL, externo
SASL e login de autenticação.
https://translate.googleusercontent.com/translate_f 222/261
22/04/2020 Indy em Profundidade
â € ¢ MLST e MLSD agora são suportados. Isso fornece um formato de lista de diretórios FTP padrão que é
facilmente analisado.
â € ¢ Um comando de combinaçà £ o especial foi adicionado para suporte a upload de multipartes. Observe que isso faz
requer um servidor que suporte o comando COMB, como o GlobalScape Secure FTP Server ou o
componente de servidor no Indy 10.
â € ¢ Um comando XCRC foi adicionado para obter o CRC dos arquivos. Observe que isso requer um
servidor que suporta o comando COMB, como o GlobalScape Secure FTP Server ou o servidor
componente no Indy 10.
â € ¢ O cliente agora suporta o comando MDTM para obter a data da última modificaçà £ o
• Calculadora OTP (senha de uso único) incorporada e o OTP agora detectado automaticamente
• Transferidor de arquivos FTPX ou site a site (onde um arquivo é transferido entre dois servidores) agora é suportado.
Page 135
Observe que as transferências FTPX somente funcionarão se o servidor suportar (muitos administradores e
os desenvolvedores agora desativam esse recurso por razões de segurança).
â € ¢ Extensões IP6 especÃficas do FTP foram adicionadas.
Agora, o recurso de transferências de site para site FTPX agora pode ser desativado. Isso é feito por razões de segurança, como
os comandos Port e PASV estão sujeitos a abusos, conforme descrito por:
â € ¢ http://www.cert.org/tech_tips/ftp_port_attacks.html
â € ¢ http://www.kb.cert.org/vuls/id/2558
â € ¢ http://www.cert.org/advisories/CA-1997-27.html
â € ¢ http://www.geocities.com/SiliconValley/1947/Ftpbounc.htm
â € ¢ http://cr.yp.to/ftp/security.html
Se surgir a chance de um sistema não suportado ser descoberto, um manipulador personalizado poderá ser usado.
https://translate.googleusercontent.com/translate_f 224/261
22/04/2020 Indy em Profundidade
â € ¢ Microware OS-9
â € ¢ Música (sistema multiusuário para computação interativa)
â € ¢ Servidor FTP NCSA para MS-DOS (CUTCP)
â € ¢ Novell Netware
Page 136
19.1.7 Outros
Outras mudanças e melhorias notáveis no Indy 10 incluem, mas não estão limitadas a:
â € ¢ Adicionadas interceptações do servidor, permitindo que você registre o servidor FTP e elas funcionam da mesma forma que
o cliente intercepta.
â € ¢ Cliente e servidores Systat UDP e TCP e foram adicionados.
â € ¢ Um componente do servidor DNS foi adicionado.
â € ¢ Conexão HTTP por meio de suporte a proxy foi adicionado.
â € ¢ TIdIPAddrMon foi adicionado para monitorar todos os endereços IP e todos os adaptadores de rede
â € ¢ suporte IP6
â € ¢ Um sistema de senha de uso único foi implementado como uma calculadora OTP para o
clientes e como um componente do gerenciador de usuários. Isso suporta hashes MD4, MD5 e SHA1.
https://translate.googleusercontent.com/translate_f 225/261
22/04/2020 Indy em Profundidade
É a crença da equipe Indy que o progresso não é sem algum sacrifício. Através de pequenas mudanças no
interfaces, grandes ganhos podem ser alcançados e isso é um Indy melhor. Sem essas mudanças, o futuro
as instruções são prejudicadas e a bagagem coletiva é retida. Assim como Winshoes para Indy 8, e depois Indy
8 a Indy 9 aumentou a abstração, o mesmo acontece com o Indy 10.
Um dos princípios principais da Indy é que é fácil programar e se baseia em um modelo de bloqueio. este
permite fácil desenvolvimento e o código do usuário não sofre serialização. O objetivo do projeto da Indy é
seja fácil de usar e rápido o suficiente para 95% das necessidades do usuário final.
Contudo, em instalações muito grandes, isso causa comutação excessiva de contexto e acumula altos
sobrecarga da linha. Essas limitações aparecem apenas em grandes instalações, com cerca de 2.000 concorrentes
threads em um aplicativo bem projetado. Na maioria dos aplicativos, as limitações no código do usuário parecem longas
antes das limitações de Indy.
Tradicionalmente, para atender aos 5% restantes dos usuários, o código facilmente escrito deve ser abandonado para
código complexo e difícil de manter, como E / S direta sobreposta, portas de conclusão de E / S ou
unidades de trabalho divididas usando roscas contra soquetes sem bloqueio. Indy 10 preserva o Indy fácil de usar
modelo de bloqueio, enquanto aumenta o desempenho internamente. Indy 10 faz isso usando o avançado
interfaces de rede e traduzi-las eficientemente para um modelo de bloqueio amigável. Indy 10 assim
destina-se a atender 99,9% das necessidades da comunidade, com apenas uma minoria muito pequena ainda exigindo
código personalizado para situações muito incomuns.
Page 137
https://translate.googleusercontent.com/translate_f 226/261
22/04/2020 Indy em Profundidade
O Indy 10 consegue isso de várias maneiras, mas as fibras são a pedra angular para essa conquista. Uma fibra é muito
semelhante a um encadeamento, mas é mais flexível e possui uma sobrecarga menor do que um encadeamento, se usado corretamente.
â € ¢ Abrir (conectar)
â € ¢ Fechar (desconectar)
â € ¢ Leia dados brutos
â € ¢ Escreva dados brutos
â € ¢ Verifique o status da conexà £ o
Essa função permitia a criação de manipuladores de IOH alternativos que executavam a E / S de outras fontes
do que uma tomada. Até a E / S padrão do soquete foi implementada usando um IOHandler padrão.
Como a funcionalidade era mínima, a implementação de IOHandlers era muito simples. Contudo
isso também fazia com que os operadores de IOH executassem suas E / S com métodos menos eficientes. Por exemplo, um
O manipulador de E / S pode estar recebendo dados de um arquivo local para gravar, mas não teria como saber como
porque ele possui apenas um método de gravação para todos os dados. Mesmo se o manipulador de E / S tivesse a capacidade de um alto
arquivo de desempenho lido, não pôde usá-lo.
Os IOHandlers do Indy 10 implementam não apenas os métodos mínimos de baixo nível, mas também os métodos de alto nível como
bem. Tais métodos de nível superior foram implementados anteriormente pelo TIdTCPConnection.
Os IOHandlers podem ser criados como antes, implementando apenas os métodos de baixo nível. A base
O IOHandler contém implementações padrão dos métodos de nível superior que usam o nível inferior
métodos. No entanto, cada IOHandler pode substituir métodos adicionais de nível superior para fornecer otimizado
implementações específicas para o IOHandler.
https://translate.googleusercontent.com/translate_f 227/261
22/04/2020 Indy em Profundidade
no Windows.
o futuro. No momento,
A necessidade nenhuma
é menos outra
urgente no interface
Linux porfoicausa
implementada no Linux,
de sua semântica mas pode estar em
de rede.
Algumas das interfaces adicionais não estão disponíveis em todas as versões do Windows e devem ser usadas
somente em implementações de servidor ou sistemas com um número muito grande de conexões de clientes. Não há
necessidade de tais implementações em aplicativos clientes normais.
â € ¢ E / S sobreposta
• Portas de conclusão de E / S
Normalmente, para usar portas de E / S sobrepostas e, mais especificamente, portas de conclusão de E / S, complicadas e altamente
código não intuitivo deve ser escrito. No entanto, com Indy 10, como antes, Indy cuida de todos esses detalhes
e apresenta ao desenvolvedor uma interface amigável e fácil de usar.
Page 138
19.2.3 Fibras
Além de expandir nosso suporte de threads, o Indy 10 contém suporte para fibras. O que é uma fibra? Em
curto, é um "Thread", mas um
isso é controlado pelo código - não pelo sistema operacional. De fato, um segmento pode ser pensado como um
fibra avançada. As fibras são semelhantes às threads do usuário Unix.
Um encadeamento é uma unidade básica à qual o sistema operacional aloca tempo. Um encadeamento contém sua própria pilha,
certos registradores de processador e um contexto de thread. Threads são agendados automaticamente pelo
sistema operacional.
https://translate.googleusercontent.com/translate_f 228/261
22/04/2020 Indy em Profundidade
Em geral, as fibras não oferecem vantagens em relação a uma aplicação multiencadeada bem projetada.
No entanto, as fibras combinadas com um agendador inteligente que possui informações pertinentes disponíveis
aumentar significativamente o desempenho através de grandes ganhos de eficiência.
Várias fibras podem ser executadas usando uma única linha. Uma única fibra pode ser executada por vários encadeamentos,
embora apenas um de cada vez. Você pode executar várias fibras dentro. O código para fazer isso pode ser bastante
complexo, mas Indy lida com tudo isso para você. All Indy
componentes, clientes e servidores, suportam fibras e de uma maneira quase transparente.
Ao usar fibras, a Indy também pode traduzir a complexa e hostil rede de camadas inferiores
interfaces em uma interface amigável para desenvolvedores.
19.2.4 Agendadores
O tecelão de fibras da Indy é um agendador que programa as fibras em um ou mais fios. Depósito de fibras
itens de trabalho em uma fila de trabalho e aguarde. Quando o item de trabalho de uma fibra estiver concluído, o
O planejador coloca a fibra em uma lista de fibras que podem ser agendadas.
Os agendadores do sistema operacional planejam encadeamentos de maneira inteligente, porém eles têm limitações
informações sobre threads, pois cada segmento é comum e genérico entre todas as tarefas em um sistema.
Os agendadores do sistema operacional podem agendar apenas com base no estado de espera e na prioridade de um encadeamento.
O tecelão de fibra da Indy (programador de fibra) usa informações avançadas específicas da tarefa a
determinar necessidades de agendamento, prioridades e estados de espera. Ao fazê-lo, o Indy pode reduzir drasticamente
o número de opções de contexto que ocorrem em relação ao trabalho concluído. Isso resulta em significativa
ganhos de desempenho.
Uma opção de contexto é quando um encadeamento é suspenso e outro é agendado. Para fazer isso, o
sistema operacional deve interromper preventivamente o caminho de execução do processador e salvar o
contexto do encadeamento armazenando vários registradores de processador na memória. Em seguida, ele deve restaurar outro
carregando os registradores do processador a partir de outro local da memória e reinicie o
caminho de execução.
Os agendadores de encadeamento devem equilibrar a necessidade de reduzir a alternância de contexto, com a necessidade de garantir
cada thread recebe tempo suficiente do processador. Mudar para frequentemente aumenta a sobrecarga e causa
sobrecarga para aumentar além de quaisquer benefícios. Mudar com pouca frequência causa interações desnecessárias
dependências de espera de encadeamento e respostas lentas porque os encadeamentos não estão recebendo o suficiente
tempo do processador.
https://translate.googleusercontent.com/translate_f 229/261
22/04/2020 Indy em Profundidade
Para gerenciar isso, os sistemas operacionais definem um período quântico ou máximo de tempo que um encadeamento pode
receber o tempo do processador por switch. Na maioria dos casos, um encadeamento renderá antes desse tempo ser alcançado por
entrando em um estado de espera. Os estados de espera ocorrem explicitamente, ou mais comumente implicitamente, criando uma operação
Page 139
chamada de sistema ou de E / S que não pode ser concluída imediatamente. Quando essa chamada ocorre, o
sistema operacional aceita o rendimento e alterna para outro encadeamento. Se o encadeamento estiver aguardando E / S ou
alguma outra operação de bloqueio, ele será colocado em um estado de espera e não será considerado para agendamento até
a operação solicitada foi concluída ou atingiu o tempo limite.
Os tecelões de fibra da Indy funcionam de maneira semelhante, mas determinam os estados de espera em um nível muito mais alto usando um
maior variedade de informações. As fibras podem ser determinadas antecipadamente como estando em espera, sem a
é necessário alternar o contexto para eles e aguardar que eles entrem no estado de espera. Indy também divide o trabalho
entre fibras e motores de corrente, que agora realizam grande parte do trabalho de baixo nível.
A divisão do trabalho permite que interfaces de rede mais eficientes sejam usadas, como conclusão de E / S
portos. As portas de conclusão de E / S são mais eficientes porque são executadas em um nível mais próximo do hardware
interface. Winsock e outras chamadas mais distantes da camada de interface de hardware devem
comunique-se com o kernel para executar a chamada real para a interface de hardware. Chamadas que
a comunicação com o kernel deve passar pela alternância de contexto para isso. Assim, cada chamada Winsock frequentemente
envolve muitas opções de contexto desnecessárias apenas para desempenhar sua função.
Os agendadores podem usar um único thread, vários threads, threads sob demanda ou mesmo um pool de threads.
https://translate.googleusercontent.com/translate_f 230/261
22/04/2020 Indy em Profundidade
Page 140
19.2.6 Correntes
O sistema de filas de trabalho, planejadores e mecanismos de cadeia em Indy são chamados de cadeias. Enquanto
As cadeias são usadas pela Indy, não se limitam ao uso interno da Indy e têm aplicativos de usuário final como
bem.
Quando cadeias são usadas, um IOHandler baseado em cadeia deposita itens de trabalho na fila de trabalho associada.
A fibra é então suspensa até que uma unidade de trabalho para ela seja concluída. Isso ocorre porque a fibra
não pode fazer nada até o resultado de
o trabalho está pronto para ser processado. Cada método IOHandler é reduzido para uma ou mais tarefas de trabalho.
Para um melhor desempenho, cada método deve resolver o mínimo possível de tarefas de trabalho especializadas.
Page 141
https://translate.googleusercontent.com/translate_f 233/261
22/04/2020 Indy em Profundidade
O trabalho de um mecanismo em cadeia é extrair tarefas de uma fila de trabalho e concluir as tarefas. Em cima de
conclusão de cada tarefa, o mecanismo da cadeia notifica o planejador e o planejador avalia quais
fibra deve ser considerada para agendamento. O mecanismo da cadeia passa para a próxima tarefa no
fila de trabalho.
Vários tipos de mecanismo de cadeia podem ser implementados para implementar portas de conclusão de E / S, Winsock,
E / S sobreposta ou outra.
19.2.8 Contextos
Nos servidores Indy 9, os dados específicos da conexão foram armazenados como parte da classe de encadeamento. Isso foi alcançado
usando a propriedade thread.data ou descendo da classe de thread do mesmo nível e adicionando novas
campos ou propriedades para armazenamento. Isso funcionou porque cada conexão possui um thread que foi
especificamente associado a essa conexão.
https://translate.googleusercontent.com/translate_f 234/261
22/04/2020 Indy em Profundidade
Os servidores Indy 10 não são implementados da mesma maneira que o Indy 9. Os threads não estão associados a
uma única conexão. De fato, ele pode não usar fios, mas fibras. Por esse motivo, o
O método anterior de armazenamento de dados no encadeamento não é mais útil.
Page 142
O Indy 10 usa um novo conceito chamado contextos. Os contextos contêm dados específicos da conexão e são
gerenciado e rastreado pela Indy.
https://translate.googleusercontent.com/translate_f 235/261
22/04/2020 Indy em Profundidade
Page 143
https://translate.googleusercontent.com/translate_f 236/261
22/04/2020 Indy em Profundidade
Seção
XX
https://translate.googleusercontent.com/translate_f 237/261
22/04/2020 Indy em Profundidade
Materiais bônus
Page 144
20 Materiais bônus
Esta seção contém materiais de bônus que não estão diretamente relacionados à Indy.
Desfrutar!
https://translate.googleusercontent.com/translate_f 238/261
22/04/2020 Indy em Profundidade
Este artigo também fornecerá orientações sobre a estimativa do trabalho envolvido na transferência de um arquivo existente.
aplicação à estrutura .net usando DCCIL / Delphi.net.
20.1.1 Termos
O foco do artigo é portabilidade e efeitos no seu código Delphi. Por esse motivo, este artigo irá
não cobrir .net em si. Ele fornecerá apenas definições para os termos básicos necessários relacionados ao .net.
20.1.1.1 CIL
Idioma intermediário comum ou apenas idioma intermediário, para abreviar. Esta é a linguagem que o
compiladores convertem o código fonte para execução no tempo de execução .net.
A IL desempenha um papel semelhante ao P-Code ou à linguagem interpretada em Java. No entanto, tem a sua
diferenças e é implementado de maneira diferente.
20.1.1.2 CLR
20.1.1.3 CTS
CTS significa Common Type System. O CTS inclui tipos .net "nativos" predefinidos que são
acessível por qualquer idioma .net. Isso significa que o número inteiro não é mais definido por cada compilador, mas
pelo CTS e, portanto, inteiro é exatamente o mesmo entre todos os idiomas .net.
No entanto, o CTS não se limita apenas ao número inteiro e inclui muitos tipos. O CTS divide os tipos
em duas categorias básicas: tipos de valor e tipos de referência.
Tipos de valor são tipos armazenados na pilha. Você pode estar familiarizado com o termo simples ou
tipos ordinais. Os tipos de valor incluem números inteiros, bytes, outras primitivas, estruturas e enumerações.
Tipos de referência são tipos armazenados na pilha, mas referências são usadas para acessá-los.
https://translate.googleusercontent.com/translate_f 239/261
22/04/2020 Indy em Profundidade
Page 145
20.1.1.4 CLS
CLS significa Common Language Specification. O CLS é simplesmente uma especificação que define o que
possui um idioma que pode e deve suportar para trabalhar com .net.
Código gerenciado é o código compilado para IL e executado pelo CLR. O objetivo geral de qualquer .net
aplicação é usar código gerenciado 100%.
Código não gerenciado é um código compilado nativo, como o compilado pelo Delphi para Windows. Não gerenciado
O código também inclui DLLs de código nativo, servidores COM e até a API do Win32. O objetivo do .net
aplicações é evitar o código não gerenciado, tanto quanto possível.
20.1.1.7 Montagem
Um assembly é uma coleção de unidades .net IL. É muito semelhante a um pacote Delphi, e o Delphi.net trata
assemblies .net como pacotes Delphi.
https://translate.googleusercontent.com/translate_f 240/261
22/04/2020 Indy em Profundidade
DCCIL é o compilador de linha de comando para Delphi que produz saída .net. DCCIL é o que é comumente
referido como o "compilador de visualização do Delphi.net" incluído no Delphi 7.
DCC é o nome do compilador de linha de comando Delphi normal e é a abreviação de exatamente isso, Delphi
Compilador de linha de comando.
Assim DCC + IL = DCCIL. Dizendo DCCIL cada vez é complicado, assim como outros
contrapartes, recebeu um nome comum de "Diesel".
O DCCIL tem opções semelhantes ao DCC com algumas extensões específicas para .net.
20.1.2.1.1 Beta
Atualmente, o DCCIL é beta e não se destina ao código de produção. Por isso, ele tem bugs,
e até muitas partes incompletas. Isso não a torna inútil, no entanto, e a Borland é regularmente
liberando versões atualizadas.
Por ser beta, também possui certas restrições de redistribuição nos programas criados com o DCCIL.
Qualquer saída criada com o DCCIL se redistribuída também deve ser redistribuída como beta.
Page 146
https://translate.googleusercontent.com/translate_f 241/261
22/04/2020 Indy em Profundidade
20.1.2.2 Delphi 8
Borland tem estado bastante quieto sobre o Delphi 8. No entanto, com base em declarações públicas, devemos esperar
para ver um Delphi 8. No entanto, não será o Delphi.net, mas uma extensão da plataforma Windows
produtos.
20.1.2.3 SideWinder
Houve notícias recentes de um projeto SideWinder da Borland. Obviamente, este não é o seu final
nome, mas o nome de código Borland atribuído a ele durante o desenvolvimento.
O SideWinder também não é Delphi.net. O SideWinder é um ambiente de desenvolvimento em C # para .net que
concorra diretamente com o Visual Studio.net da Microsoft.
20.1.2.4 Galileo
Galileo é o nome de código da Borland para uma estrutura IDE reutilizável. O primeiro produto a usar isso é
O SideWinder e o Galileo devem ser a base para o Delphi.net IDE quando lançados também.
20.1.3 Estruturas
https://translate.googleusercontent.com/translate_f 242/261
22/04/2020 Indy em Profundidade
Page 147
A estrutura .net é a biblioteca de classes que é o núcleo do .net. Essa biblioteca de classes inclui classes para
E / S, armazenamento de dados, tipos simples, tipos complexos, acesso ao banco de dados, interface do usuário e muito mais. O que
VCL é para programadores Delphi, é o que o framework .net é para programadores .net.
A API do Win32 também desapareceu e foi substituída por classes na estrutura .net que fornecem um
interface independente de plataforma melhor e abstraída. Existem disposições para acessar a API Win32
diretamente, bem como as DLLs compiladas verdadeiras. No entanto, o uso desses métodos de acesso tornará seu código
não gerenciado e não é desejável em um aplicativo .net.
20.1.3.2 WinForms
https://translate.googleusercontent.com/translate_f 243/261
22/04/2020 Indy em Profundidade
WinForms é um assembly na estrutura .net que inclui classes para formulários, botões, caixas de edição,
e outros controles da GUI para a criação de aplicativos da GUI. WinForms é uma interface gerenciada .Net para o
API Win32 e é o que o Visual Studio.net usa para criar aplicativos GUI.
20.1.3.3 RTL
O RTL que consiste nas classes de nível inferior não visuais no Delphi, como TList, TStrings, etc.
O RTL ainda está disponível no Delphi.net. Muito do que está no RTL tem contrapartes semelhantes no .net
, mas ao fornecer o RTL Borland, foi mais fácil portar o código Delphi existente sem
a necessidade de reescrever grandes seções de código e permite o código de plataforma cruzada.
20.1.3.4 CLX
Esta é a parte que fica confusa. Antes do Delphi 7, as seguintes designações eram usadas:
â € ¢ VCL - Biblioteca de componentes visuais. A VCL se refere coletivamente aos componentes visuais, não
componentes visuais e RTL.
â € ¢ CLX (pronunciado "cliques") - Biblioteca de componentes para plataformas cruzadas - o CLX se refere à nova cruz
versão da plataforma da parte visual da VCL baseada no QT e executada no Linux, bem como
Janelas.
• CLX - CLX refere-se a toda a estrutura de componentes incluída no Delphi, C ++ Builder e Kylix.
â € ¢ VCL - VCL refere-se aos componentes visuais vinculados diretamente à API do Win32.
• Visual CLX - Visual CLX refere-se aos componentes visuais de plataforma cruzada baseados no QT.
disponível em Delphi e Kylix.
â € ¢ VCL para .net - VCL para .net refere-se a uma nova VCL executada em .net e fornece uma compatibilidade
camada para aplicativos mais antigos, além de funcionalidade adicional.
Se você olhar para as novas designações, não tenho tanta certeza de que sejam consistentes. Eu acho que no futuro eles vão
levar a mais confusão. Acho NLX (Nelix?) Ou NCL (níquel?), Ou realmente algo mais consistente
pode ter sido uma escolha melhor para o VCL para .Net. Tal como está, o Visual CLX é um subconjunto do CLX, mas o VCL
for .net é um irmão do VCL, assim como o Visual CLX.
https://translate.googleusercontent.com/translate_f 244/261
22/04/2020 Indy em Profundidade
Page 148
Ok, então, se tudo isso é tão claro quanto a lama ... Vamos para o próximo tópico.
A VCL para .net refere-se a uma nova VCL executada em .net e fornece uma camada de compatibilidade para
aplicativos, além de funcionalidades adicionais.
O VCL para .net permite que aplicativos existentes sejam portados rapidamente, pois é muito semelhante ao VCL do Win32
e CLX. Isso também permite o desenvolvimento contínuo de aplicativos de plataforma cruzada. Isto é um
recurso importante que permite suporte contínuo às instalações do Windows sem a estrutura .net,
e Linux também.
Esta é definitivamente uma área de confusão para os usuários - devo usar o WinForms ou o VCL para .net para desenvolver
a GUI?
A comparação a seguir pode ajudá-lo a escolher. Uma regra rígida e rápida para todos os projetos não deve ser
estabelecidos, mas cada projeto deve ser avaliado separadamente.
https://translate.googleusercontent.com/translate_f 245/261
22/04/2020 Indy em Profundidade
Tamanho de implantação maior devido a montagens adicionais. Implantação menor porque todos os assemblies estão incluídos no
a estrutura .net.
Apenas para plataformas Win32. Subconjuntos disponíveis na estrutura .net compacta para bolso
PCs. Pode ser portado para outras implementações .net.
Alto grau de compatibilidade com o código existente. Requer alterações significativas no código existente.
Plataforma cruzada com VCL para Win32 e Visual CLX para Somente estrutura .Net.
Linux (e Windows).
Mais eficiente em algumas áreas. Não implementa todas as otimizações que a VCL faz.
O código fonte completo está disponível. Nenhum código fonte está disponível.
Page 149
https://translate.googleusercontent.com/translate_f 246/261
22/04/2020 Indy em Profundidade
Outra possibilidade é essa - você pode misturar e combinar. O VCL para .net e WinForms não são exclusivos e
podem ser usados juntos no mesmo aplicativo.
20.1.4 Adições
Algumas das adições ao Delphi.net são bastante importantes para portar aplicativos, enquanto outras não.
Os itens não vitais para a portabilidade de um aplicativo serão abordados apenas brevemente.
Para que os idiomas possam trabalhar com as classes .net e outros idiomas, eles devem usar o CTS
(Sistema de tipo comum). O Delphi.net poderia facilmente disponibilizá-los como adições ao Delphi's
tipos. Mas isso teria deixado a situação em que o código Delphi normal usava um conjunto de tipos e
interfaces para .net usaram outra. Isso resultaria em cópias constantes dos dados,
que não é a ideia por trás do .net. Essa situação seria semelhante à que existia com o COM.
Para evitar esse problema, os tipos nativos no Delphi.net foram mapeados para os tipos no CTS. Então quando
um número inteiro é declarado, na verdade é um número inteiro .net do CTS. Esse relacionamento não se limita a
tipos simples, mas também se estende aos objetos.
20.1.4.2 Namespaces
Para evitar conflitos, e também como parte do CLS (Common Language Specification), o Delphi agora
suporta namespaces. Agora, cada unidade existe dentro de um espaço para nome.
https://translate.googleusercontent.com/translate_f 247/261
22/04/2020 Indy em Profundidade
var
GStatus: System.Label;
Este é um item importante a ser observado, pois o VCL para .net está no namespace e afetará as cláusulas de uso.
Tipos aninhados permitem que definições de tipo existam dentro de outras definições de tipo.
Page 150
O .Net não implementa RTTI como o Delphi. Em vez disso, suporta algo semelhante chamado reflexão.
A reflexão desempenha o mesmo papel que o RTTI, mas funciona de maneira um pouco diferente. A reflexão depende de
atributos para executar algumas de suas funções. Para suportar isso, o Delphi.net possui extensões a declarar
atributos.
20.1.4.5 Outros
O Delphi.net também suporta muitas novas adições menores à linguagem, como dados de classe estática, registro
herança, propriedades de classe e muito mais. A maioria dos aprimoramentos se refere a recursos de classes no
nível de idioma.
Embora úteis e exigidos pelo CLS, eles não são essenciais para transportar aplicativos.
https://translate.googleusercontent.com/translate_f 248/261
22/04/2020 Indy em Profundidade
20.1.5 Restrições
O desenvolvimento para Delphi.net requer várias restrições a serem impostas. Essas restrições são para que
O código Delphi pode estar em conformidade com as restrições e requisitos do .net.
O Delphi 7 tem uma nova designação chamada "Insegura". Quando você compila código no Delphi 7, ele avisa você
sobre itens inseguros. Itens inseguros são aqueles que não podem ser usados no tempo de execução .net.
Esses avisos estão ativados por padrão e diminuem drasticamente o compilador. Portanto, se você está compilando
código que não se destina ao .net, você deve desativar os avisos não seguros. Eles produzem o que eu chamo
o "efeito C ++". Ou seja, eles tornam o compilador lento e produzem tantos avisos que o
avisos importantes são eliminados por uma alta "relação sinal / ruído".
No entanto, o Delphi 7 pode ser uma ferramenta útil para avaliar o código que você deseja portar para .net e o DCCIL
não produz avisos não seguros. Portanto, o primeiro passo é compilar seu código no Delphi 7 e
elimine os avisos não seguros.
O Delphi separa os avisos em três tipos: tipos não seguros, código não seguro e lançamentos não seguros.
20.1.5.1.1 Tipos não seguros
â € ¢ Variáveis absolutas
â € ¢ Addr (), Ptr (), Hi (), Lo (), Swap ()
â € ¢ BlockRead () e BlockWrite ()
â € ¢ Fail ()
https://translate.googleusercontent.com/translate_f 249/261
22/04/2020 Indy em Profundidade
Page 151
• Converter uma instância para uma classe que não seja um ancestral ou descendente da classe de instância
tipo.
â € ¢ Qualquer vazamento de um tipo de registro
Vários itens foram descontinuados por não serem compatíveis com .net e, portanto, são inúteis. Muitos
desses itens, você reconhecerá nas seções anteriores, pois elas são sinalizadas como inseguras.
https://translate.googleusercontent.com/translate_f 250/261
22/04/2020 Indy em Profundidade
â €não
¢ PChar. No futuro, o Delphi.net suportará o PChar como código não gerenciado. No entanto, código não gerenciado
é recomendado.
â € ¢ diretivas automatizadas e livres. Essas diretivas não se aplicam ao .net.
• declaração asm - O assembly não é suportado porque no sistema .net, o código não é compilado para
Código da máquina.
â € ¢ TInterfacedObject, que inclui AddRef, QueryInterface e Release.
â € ¢ Agregação dinâmica - use implementos. Nota: Os implementos não são implementados no atual
lançamento do DCCIL.
â € ¢ ExitProc
20.1.6 Alterações
A Borland investiu muitos recursos na preservação da compatibilidade, tanto quanto possível. E
O Delphi.net ainda é o Delphi, mas algumas coisas não podem ser preservadas de maneira compatível com versões anteriores.
20.1.6.1 Destruição
A destruição é bem diferente no Delphi.net. A maioria dos códigos não precisará ser ajustada, mas ainda é
muito importante entender como o processo é diferente.
Em uma aplicação Delphi normal, a destruição de objetos ocorre explicitamente. Ou seja, um objeto é destruído
quando o código solicita explicitamente sua destruição usando free ou destroy. A destruição também pode ocorrer como parte
de uma relação de propriedade, mas no final isso é resultado de uma chamada explícita para libertar ou destruir também
em nome do proprietário. Esse comportamento é conhecido como destruição determinística.
Page 152
A destruição determinística permite mais controle, mas também é muito propensa a vazamentos de memória. Isso também
https://translate.googleusercontent.com/translate_f 251/261
22/04/2020 Indy em Profundidade
permite erros quando um objeto liberado é posteriormente referenciado por outra referência que não estava ciente
que o objeto foi destruído.
.Net separa essas funções de finalização e desalocação de memória, devido à forma como a memória é
gerenciado em .net. .Net usa destruição não determinística para conseguir isso. Se você trabalhou com
interfaces, a semântica de contagem de referência usada para interfaces é semelhante.
Em vez de dizer explicitamente aos objetos quando devem se destruir, a referência do CLR conta os objetos.
Quando um objeto não é mais usado, é marcado para destruição.
.Net usa coleta de lixo para limpar a memória usada pelos objetos. Este é o nome do processo
que determina quais objetos não são mais necessários e desaloca a memória associada ao
eles.
O coletor de lixo .net é bastante complexo e mesmo uma introdução básica é digna de uma seção, se não
um papel completo próprio.
Além da destruição determinística versus não determinística, a coleta de lixo tem pouco impacto sobre
a portabilidade de aplicativos. Assim, para fins de portabilidade, o coletor de lixo deve ser
considerada uma "Caixa Mágica" que cuida da destruição de objetos para você.
https://translate.googleusercontent.com/translate_f 252/261
22/04/2020 Indy em Profundidade
Para remover
executar avisos não seguros,
uma compilação carregue
all. O Delphi o projeto
produzirá umadesérie
destino no Delphi
de avisos 7. ComCada
inseguros. os avisos
avisonão seguros
precisa ser ativados,
eliminado. Esse pode ser facilmente o maior passo para portar seu aplicativo.
As cláusulas de uso precisam ser convertidas para usar espaços para nome.
Se o código precisar continuar em execução no Windows e na estrutura .net, as unidades poderão ser IFDEFed como
segue. CLR é definido em Delphi.net.
usa
{$ IFDEF CLR} Borland.Win32.Windows {$ ELSE} Windows {$ ENDIF} ,
{$ IFDEF CLR} Borland.Delphi.SysUtils {$ ELSE} SysUtils {$ ENDIF} ,
{$ IFDEF CLR} Borland.Vcl.Forms {$ ELSE} Formulários {$ ENDIF} ;
Page 153
Os namespaces podem ser vistos. Os três principais são o Borland.Win32 (Windows), Borland.Delphi
(RTL) e Borland.VCL (VCL para .net).
O Delphi para .net ainda não suporta DFMs. Será no futuro, portanto, esta etapa é necessária apenas se você desejar
para usar a versão beta do DCCIL.
Como os DFMs não são suportados, todos os formulários devem ser construídos usando o código. Existem ferramentas
projetado para executar esta tarefa que foi usada com aplicativos Delphi normais e é útil para
esta tarefa.
https://translate.googleusercontent.com/translate_f 253/261
22/04/2020 Indy em Profundidade
Application.CreateForm não éde
Para definir a forma principal suportado, portanto,
um aplicativo, os formulários
defina devem ser criados
Application.MainForm manualmente
antes de como componentes normais.
chamar Application.Run.
Durante a compilação, haverá pequenas diferenças entre o VCL para .net e VCL, assim como existem
pequenas diferenças entre o VCL e o Visual CLX. Cada um deles precisará ser resolvido manualmente ou
IFDEFed.
A portabilidade não é uma recompilação simples e deve ser alocada em tempo adequado. Portar para .net leva uma
esforço necessário para portar um aplicativo VCL para o Visual CLX. Embora o tempo e o esforço
necessário é significativo, é muito menos do que uma reescrita completa e permite a criação de várias plataformas
implantação e compartilhamento de código se o planejamento adequado for realizado antes da mão.
20.1.8 Créditos
Eu tenho usado muitas fontes. Lamento se esqueci de creditar alguém. Desejo agradecer o seguinte
indivíduos: John Kaster, Brian Long, Bob Swart, Lino Tadros, Danny Thorpe, Eddie Churchill,
Doychin Bondzhev e, por último mas não menos importante, experimentação.
https://translate.googleusercontent.com/translate_f 254/261
22/04/2020 Indy em Profundidade
(C) 2003 Atozed Computer Software Ltd.
Page 154
Seção
https://translate.googleusercontent.com/translate_f 255/261
22/04/2020 Indy em Profundidade
sobre os autoresXXI
Page 155
21 sobre os autores
https://translate.googleusercontent.com/translate_f 256/261
22/04/2020 Indy em Profundidade
https://translate.googleusercontent.com/translate_f 257/261
22/04/2020 Indy em Profundidade
Page 156
Índice
-T-
fio 29
https://translate.googleusercontent.com/translate_f 258/261
22/04/2020 Indy em Profundidade
https://translate.googleusercontent.com/translate_f 259/261
22/04/2020 Indy em Profundidade
Page 157
154
https://translate.googleusercontent.com/translate_f 260/261
22/04/2020 Indy em Profundidade
Page 158
https://translate.googleusercontent.com/translate_f 261/261