我正在尝试在Linux中使用原始套接字API在网络层之上实现我自己的传输层协议,如TCP,它将被某些应用程序使用。我正在研究Ubuntu 14.04。
我能够发送和接收数据包。
现在在实现传输协议的部分,我期待写一些像
这样的函数connect(int sockfd) - 建立与服务器的连接。
send_data(int sockfd,char * data) - 发送数据
receive_data(int sockfd,char * data) - 接收数据
close(int sockfd) - 关闭连接
此外,由于我正在尝试实施类似TCP的协议,为了保持协议可靠,我想为每个接收到的数据包发送确认。我已经制作了自己的TCP标题,如下所示
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没有确认。
如果有人有任何想法,我该怎么做,或者如果我朝错误的方向走,请纠正我。提前谢谢。
我已经使用3路握手编写了connect(int sockfd)的代码,工作正常,我可以分享。
答案 0 :(得分:2)
如上所述,无法保证邮件到达目的地。如果我理解你的问题,我希望下面这个简单的例子可以帮助你。
您有客户端A和服务器B.客户端A将名为A1的数据包发送给B. B保存最后收到的数据包的名称,并用ack回复A.
如果ack进入客户端,它会发送下一个名为A2的数据包。
但是,如果ack丢失,客户端会在一段时间后重新发送名为A1的数据。 当服务器第二次收到A1时(使用保存的名称),它可以假设ack丢失了。 服务器然后重新发送确认,希望这次它将到达客户端。这种情况会持续多次。
如您所见,服务器无需知道ack是否已交付给客户端。接收重复数据包会告诉服务器确认丢失了。 (为简单起见,忽略虚假的超时)
答案 1 :(得分:0)
你正面对拜占庭将军'协议的问题:永远不能保证消息到达。如果您向确认消息发送消息,则可能无法到达;如果您发送投票以询问该消息是否已到达,则可能永远不会到达或其答案可能永远不会到达......
所以协议充其量只能是可靠的"在您的设计中,您必须包括未到达,并且您的软件必须能够应对它。 "软件"可能意味着一直到应用程序层。