Estoy tratando de implementar mi propio Protocolo de capa de transporte como TCP, que será utilizado por alguna aplicación, además de la capa de red usando la API de sockets sin formato en Linux. Estoy trabajando en Ubuntu 14.04.
He podido enviar y recibir paquetes.
Ahora, en la parte de implementar el Protocolo de transporte, espero escribir algunas funciones como
connect(int sockfd) - Para establecer conexión con el servidor.
send_data(int sockfd, char* data) - Para enviar datos
receive_data(int sockfd, char* data) - Para recibir datos
close(int sockfd) - cierra la conexión
Además, dado que estoy tratando de implementar un protocolo como TCP, para mantener el protocolo confiable, quiero enviar un reconocimiento por cada paquete de datos recibido. He hecho mi propio TCP como encabezado de la siguiente manera
typedef struct rtlp_hdr { int checksum; short int src_port; //defined by us short int des_port; //defined by us int seq_no; int ack_no; }rtlp_hdr;Ahora, en la implementación de la función send_data después de enviar un paquete de datos, espero recibir el acuse de recibo del siguiente paquete de datos por un tiempo determinado, y si no recibo ningún acuse de recibo o recibo un acuse de recibo corrupto (después de verificar la suma de verificación) Vuelvo a enviar los datos. Estoy enfrentando problemas al crear la correspondiente función receive_data para la misma, por ejemplo, ¿cómo sabría que el acuse de recibo enviado para los datos recibidos se entregó con éxito al remitente, ya que no hay acuse de recibo por acuse de recibo?
Si alguien tiene alguna idea de qué puedo hacer o si voy en la dirección equivocada, por favor corríjame. gracias de antemano.
Ya he escrito el código para connect(int sockfd) usando el protocolo de enlace de 3 vías que funciona bien, puedo compartirlo.
Como se mencionó, no hay forma de garantizar que un mensaje llegue al destino. Si entiendo bien su pregunta, espero que el ejemplo simple a continuación pueda ayudarlo.
Tiene un cliente A y un servidor B. El cliente A envía un paquete llamado A1 a B. B guarda el nombre del último paquete recibido y responde a A con un acuse de recibo.
Si el acuse de recibo llega al cliente, envía el siguiente paquete, denominado A2.
Sin embargo, si se pierde el acuse de recibo, el cliente vuelve a enviar los datos denominados A1 después de un tiempo. Cuando el servidor recibe A1 por segunda vez (utilizando el nombre guardado), puede suponer que se perdió el reconocimiento. Luego, el servidor vuelve a enviar el acuse de recibo, con la esperanza de que esta vez llegue al cliente. Esto continúa tantas veces como sea necesario.
Como puede ver, el servidor no necesita saber si el acuse de recibo ha sido entregado al cliente. La recepción de un paquete duplicado le dice al servidor que se perdió el acuse de recibo. (ignorando los tiempos de espera falsos por simplicidad)
Te enfrentas al problema de los protocolos de los generales bizantinos : nunca hay garantía de que llegue un mensaje. Si envía un mensaje para confirmar que llegó el mensaje, es posible que no llegue; si envía una encuesta para preguntar si el mensaje ha llegado, es posible que nunca llegue o que su respuesta nunca llegue...
Por lo tanto, los protocolos pueden ser, en el mejor de los casos, "principalmente confiables" y en su diseño debe incluir la no llegada, y su software debe poder manejarlo. "El software" puede significar todo el camino hasta la capa de aplicación.