Limitando o envio de TCP com uma fila "a ser enviado" e outros problemas de design

Esta pergunta é o resultado de duas outras perguntas que fiz nos últimos dias.
Estou criando uma nova pergunta porque acho que ela está relacionada ao "próximo passo" no meu entendimento de como controlar o fluxo de envio / recebimento, algo para o qual ainda não recebi uma resposta completa.
As outras questões relacionadas são:
Uma pergunta de interpretação da documentação do IOCP - ambiguidade de propriedade do buffer
Problemas de buffer TCP sem bloqueio

Em resumo, estou usando portas de conclusão de E / S do Windows.
Eu tenho vários threads que processam notificações da porta de conclusão.
Acredito que a pergunta seja independente de plataforma e teria a mesma resposta como se fosse fazer a mesma coisa em um sistema Solaris * nix, * BSD.

Então, eu preciso ter meu próprio sistema de controle de fluxo. Bem.
Então eu mando enviar e enviar, muito.Como sei quando começar a enfileirar os envios, pois o lado do receptor está limitado ao valor X?

Vamos dar um exemplo (coisa mais próxima da minha pergunta): protocolo FTP.
Eu tenho dois servidores; Um está em um link de 100 Mb e o outro está em um link de 10 Mb.
Encomendo o 100Mb um para enviar para o outro (o 10Mb vinculado) um arquivo de 1GB. Ele termina com uma taxa de transferência média de 1,25 MB / s.
Como o remetente (o vinculado de 100 Mb) sabia quando reter o envio, para que o mais lento não fosse inundado? (Nesse caso, a fila "a ser enviado" é o arquivo real no disco rígido).

Outra maneira de perguntar isso:
Posso receber uma notificação de "reter seus envios" pelo lado remoto? Ele está embutido no TCP ou o chamado "protocolo de rede confiável" precisa que eu faça isso?

É claro que eu poderia limitar meus envios a um número fixo de bytes, mas isso simplesmente não parece certo para mim.

Novamente, eu tenho um loop com muitas envios para um servidor remoto e, em algum momento, dentro desse loop, terei que determinar se devo enfileirar o envio ou posso passá-lo para a camada de transporte (TCP).
Como faço isso? O que você faria? É claro que, quando eu receber uma notificação de conclusão do IOCP de que o envio foi feito, emitirei outros envios pendentes, isso fica claro.

Outra questão de design relacionada a isso:
Como devo usar buffers personalizados com uma fila de envio, e esses buffers estão sendo liberados para serem reutilizados (portanto, não usando a palavra-chave "delete") quando uma notificação "send-done" for recebida, terei que usar uma exclusão mútua nesse buffer pool.
Usar um mutex torna as coisas mais lentas, então eu tenho pensado; Por que não cada segmento tem seu próprio pool de buffers, assim, acessá-lo, pelo menos ao obter os buffers necessários para uma operação de envio, não requer mutex, porque pertence apenas a esse segmento.
O conjunto de buffers está localizado no nível TLS (thread local storage).
Nenhum pool mútuo implica nenhum bloqueio necessário, implica operações mais rápidas, mas também implica mais memória usada pelo aplicativo, porque mesmo se um segmento já alocou 1000 buffers, o outro que está enviando agora e precisa de 1000 buffers para enviar algo precisará alocado estes para o seu próprio.

Outro problema:
Digamos que eu tenha buffers A, B, C na fila "a ser enviado".
Em seguida, recebo uma notificação de conclusão informando que o destinatário recebeu 10 dos 15 bytes. Devo reenviar a partir do deslocamento relativo do buffer ou o TCP cuidará disso para mim, ou seja, concluir o envio? E, se devo, posso ter certeza de que esse buffer é o "próximo a ser enviado" na fila ou poderia ser o buffer B, por exemplo?

Esta é uma pergunta longa e espero que ninguém tenha se machucado (:

Eu adoraria ver que alguém leva um tempo para responder aqui. Eu prometo que vou votar duas vezes nele! (:
Obrigado a todos!

questionAnswers(3)

yourAnswerToTheQuestion