Reliable UDP

OSI(Open System Interconnection,开放系统互联)模型通常划分为应用层、传输层、网络层、数据链路层、物理层,底下两层通常指随操作系统提供的驱动程序和网络硬件,传输层有TCP(Transmission Control Protocol,传输控制协议)、UDP(User Datagram Protocol,用户数据报协议)等协议,网络层有IPv4,IPv6等协议,网络应用所在的层即应用层。TCP/IP指传输层为TCP、网络层为IP的协议族。

UDP无连接,可靠性应由应用层保证。

超时重传,分组验证是要处理的两个基本问题。

考虑一问一答式的回射服务器。

要实现超时重传,就要在包中携带时间,这个时间用在计算RTT(Round-trip Timeout,回环时间)上,并在发包后alarm一个timer,它的参数是RTO(Retransmission Timeout,重传超时),这个值要根据RTT动态计算,然后pselect阻塞等待回应。如果超时到了,仍没收到回应,那么pselect就会被中断,这时候重新算RTO,再发包。

进行分组验证是在包中携带一个序列号。

怎么简单地向包中添加这些信息呢?使用sendmsg与recvmsg就可以做到。

int
main(int argc, char **argv)
{
    int sockfd;
    struct sockaddr_in servaddr;

if(argc != 2)
    {
        printf("usage: udpcli <IPaddress>\n");
        return -1;
    }

bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    servaddr.sin_addr.s_addr = inet_addr(argv[1]);

sockfd = socket(AF_INET, SOCK_DGRAM, 0);

dg_cli(stdin, sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
}

void
dg_cli(FILE *fp, int sockfd, struct sockaddr *pservaddr, socklen_t servlen)
{
    int n;
    char sendline[MAXLINE], recvline[MAXLINE];

while(fgets(sendline, MAXLINE, fp) != NULL)
    {
        n = dg_send_recv(sockfd, sendline, strlen(sendline),
                recvline, MAXLINE, pservaddr, servlen);

if(n < 0)
            return;

recvline[n] = 0;
        fputs(recvline, stdout);
    }
}

ssize_t
dg_send_recv(int fd, void *outbuff, size_t outbytes,
    void *inbuff, size_t inbytes,
    struct sockaddr *destaddr, socklen_t destlen)
{
    ssize_t n;
    fd_set rset;
    struct sigaction sa;
    sigset_t sigset_alarm, sigset_empty;
    struct iovec iovsend[2], iovrecv[2];

if(rttinit == 0)
    {
        rtt_init(&rttinfo);
        rttinit = 1;
    }

sendhdr.seq++;
    msgsend.msg_name = destaddr;
    msgsend.msg_namelen = destlen;
    msgsend.msg_iov = iovsend;
    msgsend.msg_iovlen = 2;
    iovsend[0].iov_base = &sendhdr;
    iovsend[0].iov_len = sizeof(sendhdr);
    iovsend[1].iov_base = outbuff;
    iovsend[1].iov_len = outbytes;

msgrecv.msg_name = NULL;
    msgrecv.msg_namelen = 0;
    msgrecv.msg_iov = iovrecv;
    msgrecv.msg_iovlen = 2;
    iovrecv[0].iov_base = &recvhdr;
    iovrecv[0].iov_len = sizeof(recvhdr);
    iovrecv[1].iov_base = inbuff;
    iovrecv[1].iov_len = inbytes;

sigemptyset(&sigset_alarm);
    sigemptyset(&sigset_empty);
    sigaddset(&sigset_alarm, SIGALRM); // 构造信号集
    
    sa.sa_handler = sig_alarm;
    sa.sa_flags = 0;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGALRM, &sa, NULL); // 注册alrm信号处理函数sig_alarm

rtt_newpack(&rttinfo);
    FD_ZERO(&rset);
    while(1)
    {
        sendhdr.ts = rtt_ts(&rttinfo);
        sendmsg(fd, &msgsend, 0);
        
        alarm(rtt_start(&rttinfo));
        
loop:
        FD_SET(fd, &rset);
        sigprocmask(SIG_BLOCK, &sigset_alarm, NULL); // 临时阻塞alrm信号,否则将会?考虑这样一种情况,在调pselect之前,alrm信号被触发,如果pselect只等待中断,那么它将永远阻塞
        if(pselect(fd+1, &rset, NULL, NULL, NULL, &sigset_empty) < 0)
        {
            if(errno == EINTR)
            {
                if(rtt_timeout(&rttinfo) < 0) // 超时验证
                {
                    printf("dg_send_recv: no response from server, giving up");
                    rttinit = 0;
                    return -1;
                }
            }
        }
        if(FD_ISSET(fd, &rset))
        {
            if((n = recvmsg(fd, &msgrecv, 0)) < 0)
            {
                goto loop;
            }
            if(n < sizeof(struct hdr) || recvhdr.seq != sendhdr.seq) // 分组验证
            {
                goto loop;
            }
            alarm(0);
            rtt_stop(&rttinfo, sendhdr.ts);
            return (n - sizeof(struct hdr));
        }
    }
}

时间: 2024-10-27 23:38:28

Reliable UDP的相关文章

再次对比TCP与UDP

免责声明:和往常一样,此文章的观点都属于'No Bugs'Hare(译注:一个网站) ,也许不一定和翻译者或者Overload编辑的意见一致.同时,翻译者从Lapine翻译到英语也具有一定的难度.除此之外,翻译者与Overload对于从阅读此文章所带来的后果或不作为明确不负任何责任. 原文地址:Once Again on TCP vs UDP 讨论TCP与UDP的好与坏几乎与Linux和windows的争辩有着一样长的历史.我一直支持一个观点,也就是:UDP与TCP都有各自的适用场景(比如:[N

distributed programming---lab1(basic communication of server and client)

socket() creates an endpoint for communication and returns a file        descriptor that refers to that endpoint. The lab is about basic communication of server and client. The server is iterative server which only serves one client at a time. The so

APP安全--网络传输安全 AES/RSA/ECC/MD5/SHA

移动端App安全如果按CS结构来划分的话,主要涉及客户端本身数据安全,Client到Server网络传输的安全,客户端本身安全又包括代码安全和数据存储安全.所以当我们谈论App安全问题的时候一般来说在以下三类范畴当中. App代码安全,包括代码混淆,加密或者app加壳. App数据存储安全,主要指在磁盘做数据持久化的时候所做的加密. App网络传输安全,指对数据从客户端传输到Server中间过程的加密,防止网络世界当中其他节点对数据的窃听. 这一篇我们先聊下网络传输的安全. 安全相关的基础概念

App安全之网络传输安全

移动端App安全如果按CS结构来划分的话,主要涉及客户端本身数据安全,Client到Server网络传输的安全,客户端本身安全又包括代码安全和数据存储安全.所以当我们谈论App安全问题的时候一般来说在以下三类范畴当中. App代码安全,包括代码混淆,加密或者app加壳. App数据存储安全,主要指在磁盘做数据持久化的时候所做的加密. App网络传输安全,指对数据从客户端传输到Server中间过程的加密,防止网络世界当中其他节点对数据的窃听. 这一篇我们先聊下网络传输的安全. 安全相关的基础概念

[转]Peer-to-Peer Communication Across Network Address Translators

Peer-to-Peer Communication Across Network Address Translators Bryan Ford Massachusetts Institute of Technology baford (at) mit.edu Pyda Srisuresh Caymas Systems, Inc. srisuresh (at) yahoo.com Dan Kegel dank (at) kegel.com J'fais des trous, des petits

【Darwin学习笔记】之TaskThread

[转载请注明出处]:http://blog.csdn.net/longlong530 学习TaskThread主要有三个类要关注: TaskTreadPool: 任务线程池 TaskThread:任务线程 Task: 任务 1. TaskThreadPool Darwin运行着一个或者多个任务(Task)线程,并将他们统一在线程池TaskThreadPool中管理.任务线程从事件线程中接收RTSP和RTP请求,然后把请求传递到恰当的服务器模块进行处理,把数据包发送给客户端. 缺省情况下,核心服务

UDT: Breaking the Data Transfer Bottleneck

http://udt.sourceforge.net/ DT is a reliable UDP based application level data transport protocol for distributed data intensive applications over wide area high-speed networks. UDT uses UDP to transfer bulk data with its own reliability control and c

KCP 传输协议

作者:韦易笑链接:https://www.zhihu.com/question/36258781/answer/98944369来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. KCP 传输协议:GitHub - skywind3000/kcp: KCP libenet的协议设计是非常落后的,基本上就是90年代教科书上那种标准ARQ协议实现,很难在复杂的网络条件下提供可靠的低延迟传输效果.而KCP具备更多现代传输协议的特点,诸如:流量换延迟,快速重传,流控优化,un

NetCore开源项目集合

具体见:https://github.com/thangchung/awesome-dotnet-core 半年前看到的,今天又看到了,记录下. General ASP.NET Core Documentation - The official ASP.NET Core documentation site. .NET Core Documentation - Home of the technical documentation for .NET Core, C#, F# and Visual