1. Descrição da Arquitetura O protocolo atual possui as seguintes características:
1) O cliente envia uma solicitação ao servidor, e o comprimento de cada solicitação é variável. O comprimento da solicitação é especificado no primeiro INT.
2) Cada servidor geralmente fornece serviços para vários clientes. Por exemplo, o TS precisa fornecer serviços para CP e NP ao mesmo tempo.
A CP presta serviços a NP e outros CP, sendo também cliente de outros CP, TS e SP.
3) Quando cada servidor atende a um cliente, geralmente é de longo prazo e envolve múltiplas solicitações e respostas.
Essa estrutura é projetada principalmente para suportar um grande número de conexões de clientes simultâneas. Quando há um grande número de conexões de clientes simultâneas, não importa se threads ou processos são usados, serviços eficazes não podem ser fornecidos, portanto, select deve ser usado.
Modo de votação.
2. Descrição básica da estrutura de dados: Para cada cliente, algumas informações correspondentes ao cliente precisam ser salvas CPnew.c atual, SPnew.c.
É basicamente igual à estrutura de dados central do TSnew.c, que consiste em Sessão,
Consiste em SessionCluster (em TSnew.c) ou ServerDesc (CPnew.c e SPnew.c).
Dentre eles, Session são os dados relacionados a cada cliente, e SessionCluster (ou ServerDesc) são as informações sobre cada serviço, que possui um ponteiro para cada Session relacionada ao serviço.
Esta estrutura de dados não é alocada dinamicamente quando há uma solicitação do cliente, mas foi alocada na inicialização inicial. Quando uma nova solicitação do cliente chega, o servidor procura por essas sessões pré-alocadas e descobre que há algumas inativas. e reportar um erro se não houver tempo ocioso.
Para TS e CP(SP), a maior diferença é que TS usa o protocolo UDP, enquanto CP e SP usam o protocolo TCP.
1) Para clientes do protocolo TCP, como cada cliente utiliza um soquete diferente, após a seleção, basta verificar se o fd_set de cada cliente está configurado. Para clientes UDP, é necessário encontrar o cliente correspondente. algumas medidas para reduzir a sobrecarga causada pela pesquisa.
2) No protocolo TCP, os dados enviados são na forma de um fluxo, portanto a mensagem precisa ser dividida em blocos. É possível que duas mensagens sejam lidas em uma leitura, ou uma mensagem precise ser lida várias vezes. Ambas as situações precisam ser consideradas. Portanto, cada sessão possui um buf, rstart e rlen, que são usados para armazenar mensagens que foram lidas, mas ainda não processadas.
Da mesma forma, durante o processo de escrita, também é necessário considerar que a escrita não pode ser concluída de uma só vez, por isso também é necessário reter wbuf, wstart e wlen em cada sessão. Isso é diferente no protocolo UDP. implementação, assume-se que cada pacote UDP As mensagens contidas estão todas completas, portanto, esses itens não estão incluídos.
SessionCluster (ou ServerDesc) descreve um serviço que consiste em várias partes principais:
1) meia: descreve o soquete utilizado
2) cur: o número de clientes atuais
3) max: o número máximo de clientes que podem ser acomodados
4) head: Head of Session, head[0] é a primeira sessão, head[max-1] é a última sessão
5) init: A operação de inicialização que precisa ser realizada por cada Sessão neste serviço (ponteiro de função).
6) processo: a função de processamento de mensagens neste serviço
7) encerramento: o destruidor exigido neste serviço
3. Descrição da estrutura principal
process_child: função principal, esta função é usada principalmente para definir meias e wsocks. Para SP e CP, wsocks só é definido quando wlen de Sessão> 0;
selecione;
Para cada ServerDesc (ou SessionCluster), process_type
Em SP e CP, para suportar a operação PUSHLIST, processJob deve ser executado antes de cada ciclo.
No CP, o periodCheck também é executado periodicamente para limpar conexões expiradas no TS, e o periodLog é executado periodicamente para limpar as conexões expiradas do cliente.
tipo_processo:
Para cada sessão, verifique se está legível. Se estiver legível, verifique se há uma mensagem completa.
*(unsigned int *)(rbuf+rstart) <= rlen
Chame o processo correspondente até que não haja mensagem completa para verificar se é gravável. Se for gravável e wlen> 0, escreva.
4. Outros módulos importantes
1) Módulo de configuração O módulo de configuração consiste principalmente em struct NamVal, read_config, free_config Na estrutura NamVal,
Name é o nome no arquivo cfg, ptr é o ponteiro para armazenamento e type é o tipo de dados. Atualmente, os seguintes tipos são suportados.
d: tipo inteiro, ptr é um ponteiro inteiro
s: tipo string, ptr é um ponteiro para um ponteiro, (char **)
b: Tipo de buffer de string, ptr é um char *, você deve prestar atenção ao usar este tipo, para o tipo s,
read_config alocará memória (malloc) para val, mas para o tipo b, ptr deve apontar para a memória alocada.
As duas funções importantes são:
read_config, os parâmetros são o nome do arquivo, uma estrutura NamVal * e o número de itens da estrutura NamVal
free_config, os parâmetros são os mesmos struct NamVal * e o número de itens como read_config
2) módulo mysql
O módulo mysql consiste principalmente em MYSQL *local_mysql e três funções. Essas três funções são.
init_mysql, inicializa o mysql, retorna um MYSQL *, geralmente usado para inicializar local_mysql
query_mysql, execute uma instrução mysql, o formato é query_mysql (local_mysql, "instrução mysql,
O formato é o mesmo de printf, como delete de %s, etc.", o valor necessário)
query_mysql_select, executa uma instrução mysql select Diferente do acima, ele retorna uma instrução.
MYSQL_RES*.
3) O módulo de classificação de rede é composto principalmente por estrutura de redes, função readNETBLOCK, função getnetwork, função compareNet, entre as quais,
readNETBLOCK é usado para ler o arquivo de configuração de rede e inicializar a variável global NETBLOCKS é um.
Estrutura de array de redes, com itens MAX_NET.
getnetowrk é usado para encontrar o netblock mais próximo de um endereço IP
compareNet é uma função usada no qsort para classificar os NPPeers encontrados para que os NPPeers na mesma rede sejam classificados em primeiro lugar.
4) Gerenciamento de grafo Nos atuais CP, SP e NP, o CP pode ingressar em vários canais ao mesmo tempo, e o NP também pode ter vários recursos. Para descrever esta estrutura, é introduzido o conceito de grafo. ) é armazenado um ponteiro para NP, um ponteiro para canal,
No TS também é necessário armazenar cada Intervalo desta Sessão neste Canal. Cada Canal passa pela Borda.
O cnext in é inserido em uma lista vinculada. O cabeçalho dessa lista vinculada é o PeerHead na estrutura do Canal e cada Sessão.
O enext no Edge também é encadeado em uma lista vinculada, e o cabeçalho dessa lista vinculada é o cabeçalho na estrutura da Sessão.
As funções relacionadas são:
newEdge: Adiciona uma nova borda, os parâmetros são Canal *, Sessão * Para TS, é necessário um ChannelInfo para inicializar as informações no Edge.
delEdge: Exclui uma aresta, o parâmetro é Edge *
5) Módulo de canal
As principais funções do módulo Canal são:
TS é usado para processar NEED_PEERS, SP também precisa salvar e pesquisar dados do canal, e os canais são gerenciados usando estruturas gráficas.
A pesquisa de canal usa Hash por motivos de eficiência. ChannelHash usa strings.
hash, conforme mostrado em hash_str.
O canal no TS é relativamente simples. O canal no SP e no CP também precisa gerenciar os dados relacionados ao canal. Esses dados são armazenados no diretório /var/tmp/ no disco rígido na forma de arquivos. Para cada informação relevante,
Salvo por BlockData, firstsampl, message_size, message_id e offset em BlockData armazenam informações de primeira amostra, comprimento de bloco, ID de bloco e deslocamento no arquivo, respectivamente.
O processamento de SP e CP é diferente. Para CP, os blocos são armazenados no modo hash. Por exemplo, o ID do bloco é 1000.
max_queue é 100, então o local de armazenamento é 1000%100=0. Para SP, se o recurso for um canal enviado por CS,
É uma fila circular e cada bloco é armazenado na posição correspondente em ordem. Se chegar ao final da fila, ele começa no início da fila. Se o recurso for um arquivo, as informações do BlockData não serão salvas. e o arquivo original está localizado diretamente de acordo com o blockID.
Existem muitas funções envolvendo Canal, como localizar_by_id, localizar_order_by_id, newChannel,
freeChannel, saveBlock, etc.
6) O módulo Berkeley DB está envolvido apenas no SP. Ele abre principalmente arquivos de banco de dados e consulta a localização de um determinado md5. Envolve principalmente o DB* MediaDB.
As duas funções openDB e openMedia
openDB: O parâmetro é o nome do arquivo DB
openMedia: Os parâmetros são md5 e um ponteiro inteiro, retorna FILE * e o comprimento do arquivo, no ponteiro inteiro
7) Módulo de trabalho
O módulo Job é usado em CP e SP para processar PUSHLIST. A mensagem PUSHLIST pode redefinir a lista de Job.
Você também pode adicionar ou excluir um trabalho. Isso envolve as funções em job.c e a estrutura JobDes. Uma Sessão * e um Canal * na estrutura JobDes são usados para identificar a Sessão e o Canal aos quais o trabalho pertence e. num representa o número de BlockIDs que precisam ser baixados, job é um ponteiro para um número inteiro, máscara também é um ponteiro para um número inteiro,
job[i] é o BlockID que precisa ser baixado. Se mask[i] for 0, ele precisa ser baixado. Se for 1, não é necessário.
addJob: Ao adicionar um trabalho, não verifica se o trabalho já está na lista, mas gera diretamente um trabalho e o adiciona à lista vinculada.
deleteJob: Ao excluir um trabalho, verifique todos os trabalhos na lista de trabalhos com a mesma Sessão e Canal.
Em seguida, defina a máscara correspondente do blockID que precisa ser excluído como 1.
processJob: Para cada trabalho, começando em cur, use process_P2P_REQUEST_real para transmitir o primeiro bloco com máscara 0. Se todos forem 1, exclua o trabalho.
freeJob: exclui um JobDes.
freeJobList: Exclui todos os JobDes de uma Sessão, geralmente usado quando a Sessão termina.
8) Módulo de intervalo
O módulo Intervalo é usado em TS para representar todos os intervalos rápidos em NP. Atualmente, o intervalo do bloco é identificado por um campo inicial e um campo de comprimento. As principais operações para Intervalo são mesclar e excluir, mesclar.
Ele combina o Intervalo original e a nova lista de Intervalos, enquanto a exclusão remove o novo do original.
mesclagem: O algoritmo é o seguinte, usando a lista de intervalos de buffer tmp.
if (antigo[i] < novo[j]) tmp[k] = antigo[i];
senão tmp[k] = novo[j];
Então veja quais itens antigos e novos podem ser mesclados com tmp[k]
deletar: é mais complicado, considere as seguintes situações
O início do antigo[i] é maior que o final do novo[j]
O fim do antigo[i] é antes do início do novo[j]
antigo[i] e novo[j] têm partes comuns, e
antigo[i] está contido em novo[j]
novo[j] está incluído no antigo[i] e não se inclui, novo[j] está incluído no anterior e não se inclui, e antigo[i] está incluído no anterior.
5. Alguns algoritmos rápidos
1) No TS utilizando UDP, quando o cliente efetua login pela primeira vez, é necessário encontrar uma sessão ociosa. Além disso, o cliente pode enviar mensagens de LOGIN repetidamente. já na lista de Sessões. Terceiro, quando o cliente envia uma mensagem, ele precisa encontrar a Sessão correspondente.
Para evitar essas consultas, os seguintes métodos são usados respectivamente.
Primeiro, crie uma tabela Hash. No início, todas as sessões gratuitas são vinculadas ao Hash[0]. Sempre que chega um novo cliente, a Sessão é retirada do Hash[0] e vinculada ao hashid correspondente. o valor obtido pelo hash não pode ser 0. Se for 0, o maior hashid possível é retornado.
Consultar a sessão com base na porta de origem e no endereço IP também usa esta tabela Hash.
Quando o cliente envia uma mensagem, ele usa os primeiros 3 bytes dos 7 bytes usados para verificação e usa esses 3 bytes para identificar a Sessão.
subscrito, evitando assim sobrecarga de consulta.
2) Use maxid para reduzir o número de pesquisas.
Hash não é usado em TCP. O item maxid é usado para registrar o maior id na Sessão desde a Sessão.
Durante a inicialização, a Sessão ociosa com o menor ID é pesquisada, portanto a Sessão pode ser considerada relativamente compacta.
Dado que SP e CP apoiam muito menos clientes do que TS, este tratamento é aceitável.
Quando o cliente sai, pode ser necessário atualizar o maxid. Essa atualização é concluída pelo Clientclosure.
Clientclosure atualiza maxid e então chama o destruidor correspondente.
3) Processamento de tempo limite de conexões ociosas de longo prazo Como o processamento de tempo limite requer percorrer toda a lista para economizar recursos do sistema.
Além disso, o IDLE leva muito tempo e as estatísticas do sistema geralmente precisam ser relatadas regularmente, por isso é necessário ter pontualidade.
Geralmente, periodLog ou periodCheck determinam qual das duas operações deve ser executada.
4) Ao consultar o CPPeer, considerando que atualmente apenas o GCP é suportado, o GCPCHOICE é usado diretamente, definido como o GCP com a menor carga atual e atualizado quando o GCP reporta ou o GCP faz login e logout.
6. Processamento de mensagens
1) Processamento de mensagens TS
NP2TS_LOGIN: NP efetua login no TS e faz hashes de acordo com o endereço IP de origem e o npport relatado. Se o tempo desde a última vez que a mensagem NP2TS_LOGIN foi enviada for menor que SILENCE_TIME, ele retorna diretamente, caso contrário, uma mensagem WELCOME é enviada.
NP2TS_REPORT: Informações do intervalo do relatório Se a atualização for verdadeira, ela será redefinida.
NP2TS_NEED_PEERS: Consulte informações do peer, use findCPPeer para encontrar um CP adequado, use findNPPeers
Procure um NP adequado Ao pesquisar por NP, após encontrar os resultados, eles são classificados por redes para garantir que aqueles da mesma rede sejam classificados em primeiro lugar.
NP2TS_LOGOUT: Sair
NP2TS_RES_LIST: Envie todos os RESOURCE do NP atual, use addSession para processamento, caso essa borda ainda não exista, adicione-a
NP2TS_REQ_RES: Adicionar RES e retornar pares
NP2TS_DEL_RES: Excluir RES
CP2TS_REGISTER: Faça login, CP faça login no TS, faça hashes de acordo com o endereço IP de origem e npport relatado,
Se for ILENCE_TIME desde a última vez que CP2TS_REGISTER foi enviado, retorne diretamente, caso contrário, envie
Mensagem de BEM-VINDO.
CP2TS_UPDATE: relatar carga de CP
CP2TS_NEED_PEERS: usado para consulta ECP, ainda não usado
2) Processamento de mensagens SP
P2P_HELLO: Entre em um canal,
Se o canal existir, se for um arquivo de mídia: Retorna SPUPDATE, indicando o blockID mínimo e máximo deste canal
Caso contrário: Se este canal tiver finalizado, retorne a informação de fim. Caso o canal não exista, se for um arquivo de mídia: Retorne SPUPDATE, indicando o blockID mínimo e máximo deste canal, crie o canal. indicar um erro.
P2P_PUSHLIST: redefinir ou adicionar ou excluir lista de tarefas Ao redefinir, exclua todas as tarefas relacionadas primeiro e depois adicione ou exclua.
CS2SP_REGISTER: Criar canal
CS2SP_UPDATE: Atualizar informações do canal
CS2SP_BLOCK: Enviar bloco de dados
3) Processamento de mensagens CP
P2P_HELLO: Entre em um canal e estabeleça uma conexão correspondente com base no endereço SP fornecido
P2P_PUSHLIST: redefinir ou adicionar e excluir lista de tarefas
P2P_SPUPDATE: SPUPDATE enviado por SP, se for um arquivo Media, não será encaminhado para NP
P2P_RESPONSE: Bloco de dados enviado por SP.
Além disso, a CP também precisa de se registar na TS.
Atualmente apenas um tipo de GCP está em uso.
Expandir