o mais correto seria trabalhar com camadas
http://en.wikipedia.org/wiki/OSI_model
voce jah esta com a camada 1 definida como sendo o RS232, agora precisa escolher o que vai usar na camada 2. no caso de RS232, eh comum o uso de HDLC:
http://en.wikipedia.org/wiki/HDLC
no caso do HDLC, os frames de dados sao delimitados pelo caracter 0x7E. quando voce recebe um 0x7E, voce comeca a armazenar o frame de dados ateh encontrar outro 0x7E. para conseguir transmitir dados que contem o proprio 0x7E, voce usa uma sequencia de escape, que eh o 0x7D. assim, se vc precisar transmitir um 0x7E, vc transmite um 0x7D7E. o proprio 0x7D seria transmitido como 0x7D7D, isso permite recuperar os dados originais e alerta o codigo de recepcao de que nao se trata de um delimitador de frame. se o frame nao exceder o tamanho maximo que vc definir e voce receber o delimitador indicando o fim do frame, basta fazer a verificacao de CRC e aceitar ou descartar o frame.
obviamente eh necessario fazer a retransmissao dos frames que sao descartados, entao vc precisa de uma camada 4, como o TCP:
http://en.wikipedia.org/wiki/Transmission_Control_Protocol
como voce nao vai organizar isso em rede, nao existe necessidade de implementar uma camada 3, como o IP. e tambem nao precisa necessariamente implementar o proprio TCP, mas pode adotar a ideia chave. o TCP um fluxo de dados em segmentos pequenos, que sao encapsulados nas camadas anteriores e enviados pela rede. esses segmentos podem, eventualmente, serem perdidos ou passarem por caminhos diferentes, assim cabe ao TCP colocar eles na ordem correta e perceber quem esta faltando. assim, cada segmento TCP tem um numero de serie que indica onde ele deve ser encaixado.
se vc transmitir 3 segmentos, numerados como 1, 2 e 3, supondo que a camada de enlace descarte o frame 2 em funcao de algum problema de CRC, o receptor enviaria um ACK-1 e ACK-3, indicando que recebeu os frames 1 e 3 corretamente. o transmissor, que jah estaria a essa altura transmitindo os segmentos 4, 5 e adiante, notaria a falta de um ACK para o segmento 3 e retransmitiria por precaucao, continuando entao a transmitir os proximos segmentos que nao foram ainda transmitidos.
no lado do receptor, ele provavelmente receberia o segmento 3, encaixaria o segmento faltante e enviaria o ACK-3, jah tendo provavelmente recebido os segmentos 4, 5 e adiante. com o recebimento do segmento 3, um grande segmento de dados jah estaria pronto para ser repassado para a camada acima.
e se o frame com o ACK-3 fosse perdido ? bom, o transmissor notaria que jah transmitiu mais meia duzia de segmentos, incluindo o segmento 3 duas vezes e nao recebeu resposta sobre ele, entao ele enviaria mais uma vez o segmento. o receptor, por sua vez, sabendo que o segmento jah nao eh mais necessaria, enviaria um ACK-3 apenas para satisfazer as necessidades do transmissor.
note que enviar um NACK para um frame que foi descartado nao eh uma ideia muito inteligente: se o frame foi descartado pq o CRC nao batia, provavelmente voce nao tem uma forma de dizer qual frame foi descartado, pois o conteudo dele era ilegivel. outro problema eh que pode ser um problema momentaneo na parte fisica e o frame com o NACK pode nao chegar.
assim, cada lado trabalha sempre na pior hipotese em relacao ao outro lado. para isso existe uma redundancia, claro, no exemplo acima o transmissor chegou a enviar 3x o mesmo frame. isso eh um pior caso, onde o mesmo frame foi descartado na ida e seu ACK acabou sendo descartado na volta, mas em uma situacao real teriamos a garantia de que os segmentos de dados estariam completos.
por outro lado, a vantagem de trabalhar em camadas eh que voce pode trocar, por exemplo, a camada fisica, e continuar utilizando as outras camadas no futuro, alem de dividir melhor as coisas e facilitar o desenvolvimento: voce divide um problema grande e dificil em varios problemas pequenos e faceis.
considere isso tb um incentivo para usar frames pequenos. como a camada 4 pode reconstruir segmentos longos de dados, voce pode quebrar uma estrutura de 3KB em 12 frames de 256 bytes. entao, se um frame for perdido, voce precisa reenviar apenas 1/12 a mais de informacao, 12x menos do que enviar novamente um frame de 3KB. isso poderia ser feito por uma camada 5, de controle de sessao! assim voce teria em cada segmento o numero da sessao e o numero do segmento, isso permitiria ter varias sessoes em paralelo. uma sessao poderia transmitir um fluxo de dados bidirecional continuo (como um prompt de comando) ou dados discretos, como estruturas de dados de tamanho variado. a camada 5 de sessao iria estabelecer sessoes separadas e em cada sessao a camada 4 iria reconstruir os segmentos novamente na forma de estruturas maiores. e voce nao precisaria se preocupar com a seguranca dos dados, porque a camada 2 esta fazendo isso para voce
