关于实施新的传输协议

Regarding implementing a new transport protocol

我正在尝试实现我自己的传输层协议,如 TCP,它将被某些应用程序使用,在网络层之上使用 Linux 中的原始套接字 API。我正在研究 Ubuntu 14.04.

我已经能够发送和接收数据包了。

现在在实现传输协议的部分,我期待着写一些像

这样的功能

connect(int sockfd) - 建立与服务器的连接。

send_data(int sockfd, char* data) - 发送数据

receive_data(int sockfd, char* data) - 接收数据

close(int sockfd) - 关闭连接

此外,由于我正在尝试实现像 TCP 这样的协议,为了保持协议的可靠性,我想为每个接收到的数据包发送确认。我已经制作了自己的 TCP,如下所示 header

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;

现在在 send_data 函数的实现中,在我发送一个数据包后,我等待在给定时间内接收下一个数据包的确认,如果我没有收到任何确认,或者我收到损坏的确认(检查校验和后)我重新发送数据。我在为此创建相应的 receive_data 函数时遇到问题,比如我怎么知道为接收到的数据发送的 ack 已成功传递给发件人,因为没有 ack 的 ack。

如果有人对我有任何想法,或者我走错了方向,请指正我。提前致谢。

我已经使用 3 次握手为 connect(int sockfd) 编写了运行良好的代码,我可以分享它。

您正面临协议的拜占庭将军问题:永远无法保证消息一定会到达。如果您发送消息以确认消息已到达,则它可能未到达;如果您发送投票以询问消息是否已到达,它可能永远不会到达或者它的答案可能永远不会到达...

因此协议最多可以是 "mostly reliable",并且在您的设计中您必须包括未到达,并且您的软件必须能够处理它。 "The software"可能意味着一直到应用层。

如前所述,无法保证消息到达目的地。如果我没看错你的问题,希望下面的简单例子能帮到你。

你有一个客户端A,一个服务器B。客户端A发送一个名为A1的数据包给B。 B保存最后收到的数据包的名称,并用ack回复A。

如果 ack 到达客户端,它会发送下一个名为 A2 的数据包。

但是,如果ack丢失了,客户端会在一段时间后重新发送名为A1的数据。 当服务器第二次收到 A1 时(使用保存的名称),它可以假设 ack 丢失了。 服务器然后重新发送确认,希望这次它能到达客户端。这会根据需要继续多次。

如你所见,服务端不需要知道ack是否已经发送给客户端。收到重复的数据包会告诉服务器 ack 丢失了。 (为简单起见忽略虚假超时)