原创

UDP网络通讯/UDP可靠性实现

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zyl_1102179268/article/details/73730242

UDP网络通讯

在前面一篇博客中写道TCP套接字的网络通讯TCP网络通讯;下面来介绍UDP套接字的网络通讯。

一、UDP与TCP的区别:

  • TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议

  • UDP是一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。可靠性由上层应用实现,所以要实现UDP的可靠性传输,必须通过应用层来实现和控制。

二、TCP如何实现可靠性传输

  • 请求与应答

  • 按序到达

  • 丢包,运行重传机制

  • 面向连接

  • 通过滑动窗口进行流量控制

  • 超时重传

  • 接收方缓冲满后,发送方定时询问滑动窗口容量

  • 网络拥塞避免

三、UDP的通讯实现

服务器端与客户端的接口介绍

一、 创建套接字文件

int socket(int domain, int type, int protocol);
  • domain:AF_INET,表示IPv4;

  • type:在TCP中是SOCK_STREAM表示流式服务,在UDP中为SOCK_DGRAM表示数据报服务
    二、绑定服务器端的结构体

int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen);
  • 服务器端绑定的是自己本地的信息
    三、因为UDP是无连接的,所以,我们不需要想TCP中一样设置连接,监听;
    所以,UDP就已经可以开始进行数据的发送与接受了:
    UDP中的接收端接口:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *adddrlen);
  • 在服务器端,接受的客户端的消息,所以得自己创建一个客户端的结构体进行绑定;

UDP中发送端接口:

int sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
  • 在客户端发送的消息是去服务器端,所以绑定的是服务器端的struct;

服务器端(server)代码实现

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>



static void usage(const char* proc)
{
    printf("Usage: %s[local_ip] [local_port]\n", proc);
}


int main(int argc, char *argv[])
{
    if(argc != 3)
    {
        usage(argv[0]);
        return 1;
    }

    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if(sock < 0)
    {
        perror("socket");
        return 2;
    }

    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_addr.s_addr = inet_addr(argv[1]);
    local.sin_port = htons(atoi(argv[2]));
    if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0)
    {
        perror("bind");
        return 3;
    }
    printf("bind success...\n");

    struct sockaddr_in client;
    socklen_t len = sizeof(client);
    char buf[1024]; 

    while(1)
    {
        ssize_t s = recvfrom(sock, buf, sizeof(buf)-1, 0, (struct sockaddr *)&client, &len);
        if(s > 0)
        {
            buf[s] = 0;
            printf("client#:%s", buf);
            sendto(sock, buf, sizeof(buf)-1, 0, (struct sockaddr *)&client, len);
        }
        else 
        {
            close(sock);
            printf("client quit...\n");
            break;
        }
    }
    return 0;
}

客户端(client)代码实现

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>



static void usage(const char* proc)
{
    printf("Usage: %s[local_ip] [local_port]\n", proc);
}


int main(int argc, char *argv[])
{
    if(argc != 3)
    {
        usage(argv[0]);
        return 1;
    }

    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if(sock < 0)
    {
        perror("socket");
        return 2;
    }

    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr(argv[1]);
    server.sin_port = htons(atoi(argv[2]));
    socklen_t len = sizeof(server);
    char buf[1024]; 

    while(1)
    {
        printf("server to ###");
        fflush(stdout);

        ssize_t s = read(0, buf, sizeof(buf)-1);
        if(s > 0)
        {
            buf[s] = 0;
            sendto(sock, buf, sizeof(buf)-1, 0, (struct sockaddr *)&server, len);
        }
        s = recvfrom(sock, buf, sizeof(buf)-1, 0, (struct sockaddr *)&server, &len);
        if(s > 0)
        {
            printf("client echo$:%s",buf);             
        }
    }
    return 0;
}

UDP如何实现可靠性传输 ##

       UDP它不属于连接型协议,因而具有资源消耗小,出路速度快的有点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为他们即使偶尔丢失一两个数据包,也不会对接受结果产生太大影响。
      传输层无法保证数据的可靠传输,只能通过应用层来实现了。实现的方式可以参考tcp可靠性传输的方式,只是实现不在传输层,实现转移到了应用层。
      如果不利用Linux协议栈以及上层socket机制,自己通过抓包和发包的方式实现可靠性传输,那么必须实现如下功能:

  • 发送:包的分片、包确认、包的重发

  • 接受:包的调序、包的序号确认

      目前开源程序利用UDP实现了可靠的数据传输。分别为RUDP,RTP,UDT。

RUDP

      RUDP提供了一组数据服务质量增强机制,如拥塞控制的改进、重发机制及淡化服务器算法等,从而在包丢失和网络拥塞的情况下,RTP客户机(实时位置)面前呈现的就是一个高质量的RTP流。在不告饶协议的实时特性的同时,可靠UDP的拥塞控制机制允许TCP方式下的流控制行为。

RTP

      实时传输协议为数据提供了具有实时特征的端对端传送服务,如在组播或单播网络服务下的交互视频音频或模拟数据。应用程序通常在UDP上运行RTP以便使用其多路节点和校验服务;这两种协议都提供了传输层协议的功能。但是RTP可以与其他适合的底层网络或传输层协议一起使用。如果底层网络提供组播方式,那么RTP可以使用该组播表传输数据到多个目的地。
      RTP 本身并没有提供按时发送机制或其它服务质量(QoS)保证,它依赖于底层服务去实现这一过程。 RTP 并不保证传送或防止无序传送,也不确定底层网络的可靠性。 RTP 实行有序传送, RTP 中的序列号允许接收方重组发送方的包序列,同时序列号也能用于决定适当的包位置,例如:在视频解码中,就不需要顺序解码。

UDT

      基于UDP的数据传输协议是一种互联网数据传输协议。UDT的主要目的是支持高速广域网上的海量数据传输,而互联网上的标准数据传输协议TCP在搞带宽长距离网络性能上很差,UDT建立与UDP之上,并引入新的拥塞控制和数据可靠性控制机制,UDT是面向连接的双向的应用层协议。他同时支持可靠的数据流传输和不封可靠的数据报传输。由于UDT完全在UDP上实现,它也可以应用在除了高速数据传输之外的其它应用领域,例如点到点技术(P2P),防火墙穿透,多媒体数据传输等等。
详细介绍的连接:udp如何实现可靠性传输

展开阅读全文

没有更多推荐了,返回首页

博客模板©2019 由CSDN提供 模版主题为:skin3-template by CSDN官方博客 设计