Pergunta

Estou tentando escrever algum código Python que estabelecerá um relé invisível entre dois soquetes TCP. Minha técnica atual é configurar dois threads, cada um lendo e posteriormente escrevendo 1kb de dados por vez em uma direção específica (ou seja, 1 thread para A a B, 1 thread para B a A).

Isso funciona para alguns aplicativos e protocolos, mas não é à prova de falhas - às vezes aplicativos específicos se comportam de maneira diferente ao percorrer esse relé baseado em Python. Alguns até batem.

Eu acho que isso ocorre porque, quando termino de realizar uma leitura no soquete A, o programa que executa lá considera seus dados que já chegam a B, quando eu - o homem desonesto no meio - ainda não o enviou para B. Em uma situação em que B não está pronto para receber os dados (em que send() Blocos por um tempo), agora estamos em um estado em que um acredita que enviou dados com sucesso para B, mas ainda estou mantendo os dados, esperando o send() Ligue para executar. Eu acho que essa é a causa da diferença de comportamento que encontrei em alguns aplicativos, usando meu código de retransmissão atual. Eu perdi alguma coisa, ou isso soa correto?

Nesse caso, minha verdadeira pergunta é: existe uma maneira de contornar esse problema? É possível ler apenas a partir do soquete A quando sabemos que B está pronto para receber dados? Ou há outra técnica que eu posso usar para estabelecer um relé bidirecional verdadeiramente 'invisível' entre soquetes [já abertos e estabelecidos] TCP?

Foi útil?

Solução

É possível ler apenas a partir do soquete A quando sabemos que B está pronto para receber dados?

Claro: Use select.Select Nos dois soquetes A e B (se retornarem dizendo que apenas um deles está pronto, use -o no outro) e só leia de A e escreva para B quando souber que ambos estão prontos. Por exemplo:

import select

def fromAtoB(A, B):
    r, w = select.select([A], [B], [])
    if not r: select.select([A], [], [])
    elif not w: select.select([], [B], [])
    B.sendall(A.recv(4096))

Outras dicas

Eu não acho que é provável que seja o seu problema.

Em geral, o aplicativo de envio não pode dizer quando o aplicativo de recebimento realmente chama Recv () para ler os dados: o remetente send () pode ter concluído, mas as implementações do TCP no sistema operacional de origem e destino estarão fazendo buffer, controle de fluxo , retransmissão, etc.

Mesmo sem o seu revezamento no meio, a única maneira de A "considerar seus dados que já chegou a B" é receber uma resposta de B dizendo "sim, eu entendi".

Talvez o aplicativo que você esteja proxy seja mal escrito.

Por exemplo, se eu ligar recv(fd, buf, 4096, 0); Não sou prometido 4096 bytes. O sistema cria um melhor esforço para fornecê-lo.

Se 1k não é um múltiplo do seu aplicativo recv ou send Tamanhos e o aplicativo é interrompido e, em seguida, agrupar os dados enviados em blocos 1K quebrará o aplicativo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top