当前位置:   article > 正文

2022.9.06 UDP的优缺点,UDP适用场合,UDP实现客户端与服务端的通信步骤,UDP实现客户端与服务端的通信的完整代码。_udp的优点

udp的优点

传输层协议:UDP(user Datagram protocol)<用户数据报协议>

UDP的优缺点:

优点:(1):具有高效率的数据传输的特性。

           (2):不用其他函数编写,就能够实现多客户端发送至服务端。

缺点:面向一种无连接的传输层协议,它不能够保证可靠性通信,可能会造成数据丢失,数据失序,数据重复发送等问题。

UDP适用场合:

    1. 发送小尺寸数据(如对DNS服务器进行IP地址查询时)
    2. 在接收到数据,给出应答较困难的网络中使用UDP。(如:无线网络)
    3. 适合于广播/组播式通信中。
    4. MSN/QQ/Skype等即时通讯软件的点对点文本通讯以及音视频通讯通常采用UDP协议
    5. 流媒体、VOD、VoIP、IPTV等网络多媒体服务中通常采用UDP方式进行实时数据传输

UDP实现客户端与服务端的通信步骤:

创建客户端步骤:

(1):创建UDP套接字。  socket()函数;成功:返回非负套接字描述符,失败:返回-1。

(2):设置对方的ip地址和端口号。

(3):发送消息。  sendto()函数; 成功:返回实际收到的字节数,失败:返回-1.

(4):关闭socket的对象 。close()函数

创建服务端步骤:

(1):创建UDP套接字。  socket()函数;成功:返回非负套接字描述符,失败:返回-1。

(2):绑定自己的ip地址和端口号。bink()函数 ;成功:返回0;失败:返回-1.

(3):接受收数据。   recvfrom()函数  成功:返回实际接受的字节数。失败:返回-1.

(4):关闭socket的对象 。close()函数

UDP实现客户端与服务端的通信的完整代码:

客户端代码:********************************************************

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

int main(int argc,char *argv[])
{
    if(argc < 3)
    {
        printf("pease enter IP & port\n");
        return -1;
    }
    /*
     * UDP_socket是socket函数的返回值。
     *AF_INET是socket函数的第一个传入值。代表IPv4协议
     *SOCK_DGRAM是socket函数的第二个传入值。代表数据报套接字。
     *0是socket函数的第三个传入值。一般都是0。
     */
    //创建套接字
    int UDP_socket = socket(AF_INET,SOCK_DGRAM,0);
    if(UDP_socket < 0)
    {
        perror("socket error!");
        return -1;
    }
    printf("socket ok!\n");
    //设置对方的ip和端口号
    //sockaddr_in系统通用结构体,也是存储ip,端口号等信息的专属结构体
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(atoi(argv[2]));
    server.sin_addr.s_addr = inet_addr(argv[1]);
    //发送数据
    char buf[50] = {'\0'};
    while(1)
    {
        printf("send:");
        //fgets()函数是标准IO从键盘输入数据
        fgets(buf,sizeof(buf),stdin);
        /*解释函数sendto

          *UDP_socket是sendto发送函数的第一个传入值,表示套接字描述符
         *buf是sendto发送函数的第二个传入值,表示发送缓冲区首地址
         *strlen(buf)是sendto发送函数的第三个传入值,表示发送数据的长度
         *(struct sockaddr*)这表示强制类型转换
         *(struct sockaddr*)&server 是sendto发送函数的第五个传入值。表示接受方套接字的ip地址                和端口号
         *sizeof(server) 是sendto 发送函数的第六个传入值。表示地址的长度。
         */
        sendto(UDP_socket,buf,strlen(buf),0,(struct sockaddr*)&server,sizeof(server));

    }
    //关闭socket的对象UDP_socket.
    close(UDP_socket);
    return 0;
}

************************************************************************************

服务端代码:*******************************************************************

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

int main(int argc,char *argv[])
{
    if(argc < 2)
    {
        perror("please enter port!");
        return -1;
    }
    /*
     * UDP_socket是socket函数的返回值。
     *AF_INET是socket函数的第一个传入值。代表IPv4协议
     *SOCK_DGRAM是socket函数的第二个传入值。代表数据报套接字。
     *0是socket函数的第三个传入值。一般都是0。
     */
    //创建套接字
    int UDP_socket = socket(AF_INET,SOCK_DGRAM,0);
    if(UDP_socket < 0)
    {
        perror("socket error!");
        return -1;
    }
    printf("socket ok!\n");
    //设置自己的ip和端口号
    //sockaddr_in系统通用结构体,也是存储ip,端口号等信息的专属结构体
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(atoi(argv[1]));
    //系统自动自动获取ip地址
    server.sin_addr.s_addr = INADDR_ANY;
    //进行与客户端绑定
    if(bind(UDP_socket,(struct sockaddr*)&server,sizeof(server))<0)
    {
        perror("bink error!");
        return -1;
    }
    printf("bink ok!\n");

    struct sockaddr_in src;
    int len = sizeof(src);
    char buf[50] = {'\0'};
    while(1)
    {
        //每一次清空buf缓冲区的空间
        memset(buf,0,sizeof(buf));
        /*
         * UDP_socket是recvfrom接受数据函数的第一个传入值,表示套接字描述符
         *buf是recvfrom接受函数数据的第二个传入值,表示存放接受数据的缓存区
         *strlen(buf)是recvfrom接受数据函数的第三个传入值,表示接受数据的长度
         *(struct sockaddr*)这表示强制类型转换
         *(struct sockaddr*)&server 是recvfrom发送函数的第五个传入值。表示接受方套接字的ip地             址 和端口号
         *sizeof(server) 是recvfrom 接受数据函数的第六个传入值。表示地址的长度。
         */
        recvfrom(UDP_socket,buf,sizeof(buf),0,(struct sockaddr*)&src,&len);
        printf("recv:ip = %s port = %d  %s\n",inet_ntoa(src.sin_addr),ntohs(src.sin_port),buf);
    }
    //关闭socket的对象UDP_socket.
    close(UDP_socket);
    return 0;
    }

*****************************************************************************

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/585030
推荐阅读
相关标签
  

闽ICP备14008679号