关于实施新的传输协议
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 丢失了。 (为简单起见忽略虚假超时)
我正在尝试实现我自己的传输层协议,如 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 丢失了。 (为简单起见忽略虚假超时)