Relé de dados baseado em kernel (Linux) entre dois sockets TCP

eu escreviServidor de retransmissão TCP que funciona como roteador peer-to-peer (supernode).

O caso mais simples são dois soquetes abertos e dados retransmitidos entre eles:

clientA <---> servidor <---> clientB

No entanto, o servidor tem que servir cerca de 2000 tais pares A-B, ou seja. 4000 soquetes ...

Existem duas implementações de relay de fluxo de dados bem conhecidasuserland (baseado emsocketA.recv () -> socketB.send () esocketB.recv () -> socketA.send ()):

uso deselecionar / votação funções (método não bloqueador)uso de fios / garfos (método de bloqueio)

Eu usei threads assim, no pior dos casos, o servidor cria threads 2 * 2000! Eu tive que limitar o tamanho da pilha e funciona, mas é a solução certa?

Núcleo da minha pergunta:

Existe uma maneira de evitar a transmissão de dados ativos entre dois soquetes no userland?

Parece que há um caminho passivo. Por exemplo, eu posso criar descritor de arquivo de cada soquete, criar dois canais e usar dup2 () - o mesmo método como redirecionar stdin / out. Em seguida, dois segmentos são inúteis para a retransmissão de dados e podem ser concluídos / fechados.A questão é se o servidor deve fechar sockets e pipes e como saber quando o pipe está quebrado para registrar o fato?

Eu também encontrei "pares de sockets", mas não tenho certeza sobre isso para o meu propósito.

Que solução você aconselha a descarregar o userland e limitar a quantidade de threads?

Algumas explicações extras:

O servidor definiu uma tabela de roteamento estática (por exemplo, ID_A com ID_B - identificadores pareados). O cliente A se conecta ao servidor e envia ID_A. Em seguida, o servidor aguarda o cliente B. Quando A e B estão emparelhados (ambos os sockets abertos), o servidor inicia a transmissão de dados.Os clientes são dispositivos simples por trás do NAT simétrico, portanto, o protocolo N2N ou as técnicas NAT de passagem são muito complexas para eles.

Graças a Gerhard Rieger eu tenho a dica:

Estou ciente de duas maneiras de espaço do kernel para evitar a leitura / gravação, recv / enviar no espaço do usuário:

Enviar arquivoemenda

Ambos têm restrições quanto ao tipo de descritor de arquivo.

dup2 não ajudará a fazer algo no kernel, AFAIK.

Man pages:emenda (2) emenda (2) vmsplice (2) sendfile (2) camiseta (2)

Links Relacionados:

Entendendo sendfile () e splice ()http://blog.superpat.com/2010/06/01/zero-copy-in-linux-with-sendfile-and-splice/http://yarchive.net/comp/linux/splice.html (Linus)C, sendfile () e send () diferença?colmatar entre dois descritores de arquivoEnviar e receber um arquivo em programação de soquete no Linux com C / C ++ (GCC / G ++)http://ogris.de/howtos/splice.html

questionAnswers(2)

yourAnswerToTheQuestion