UDP介绍及UDP发送端和接收端广播代码

UDP介绍

UDP(User Datagram Protocol,用户数据报协议)是一种无连接的、不可靠的传输层通信协议,它在OSI模型的第四层,即传输层中运行。UDP设计简单,不提供数据包分组、组装和排序,因此它不保证数据传输的可靠性和顺序性,但它的优点是传输速度快,延迟低,适合实时性要求高、允许一定数据丢失的应用场景。可以用于视频、语言、音频等传输。

UDP特点

无连接:

UDP在发送数据之前不需要建立连接。这意味着发送端可以在任何时候发送数据包,而不需要预先通知接收端。这种无连接的特性使得UDP的开销比TCP小,因为它不需要维护连接状态。

不可靠性:

UDP不保证数据包的到达、顺序或完整性。如果数据包在传输过程中丢失,UDP不会尝试重新发送。因此,使用UDP的应用程序需要自己处理数据包的丢失、重复或乱序问题。

高效性:

UDP的头部开销小,只有8字节(即不发送任何数据),而TCP的头部至少有20字节。这使得UDP在传输小数据包时更加高效。

实时性:

UDP适合实时应用,如在线游戏、语音通话和视频会议,这些应用通常可以容忍一定程度的数据丢失,但要求低延迟和快速的数据传输。

广播和多播:

UDP支持广播(向同一网络中的所有主机发送数据)和多播(向一组特定的主机发送数据),而TCP只支持点对点的通信。

数据包大小限制:

UDP数据包的最大长度受限于IP协议,通常为65535字节(包括UDP头部和数据)。然而,实际网络中通常会有更小的MTU(最大传输单元)限制,因此数据包可能会被分片传输。

简单性:

UDP协议简单,易于实现和理解。它没有复杂的握手过程、流量控制或拥塞控制机制。

UDP实现广播的代码思路

发送端

1.先socket创建套接字;2.用setsockopt设置套接字为广播属性;3.创建struct sockaddr_in xxx 结构体,把家族协议、端口号和广播地址添加进结构体;4.用sendto发送数据

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdlib.h>

#define MSG_LEN 256
#define BROADCAST_ADDR  "192.168.xxx.255"

int main()
{
    int sock_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(sock_fd == -1)
    {
        perror("socket...");

        return -1;
    }
    int flag = 1;
    if(setsockopt(sock_fd,SOL_SOCKET,SO_BROADCAST,&flag,sizeof(flag))== -1)
    {
        perror("setsockopt...");
        return -1;
    }
    
    struct  sockaddr_in broadcast_inf;
    memset(&broadcast_inf,0,sizeof(broadcast_inf));

    broadcast_inf.sin_family = AF_INET;
    broadcast_inf.sin_port   = htons(8888);
    broadcast_inf.sin_addr.s_addr  = inet_addr(BROADCAST_ADDR);

    while(1)
    {
        char msg[MSG_LEN] = "You hao!";
        if(sendto(sock_fd,msg,strlen(msg),0,(struct sockaddr*)&broadcast_inf,sizeof(broadcast_inf)) == -1)
        {
            perror("sendto...");
            return -1;
        }
    }
   
   if(close(sock_fd) == -1)
   {
    perror("close...");
    return -1;
   }

   return 0;
}

接收端

1.socket创建套接字;2.创建结构体struct sockaddr_in xxx 填入自己的信息用于绑定;3.用bind绑定套接字;4.recvfrom接收广播的信息

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdlib.h>

#define MSG_LEN 256

int main()
{
    int sock_fd = socket(AF_INET,SOCK_DGRAM,0);
    if(sock_fd == -1)
    {
        perror("socket...");
        return -1;
    }
     struct sockaddr_in own_inf;
     memset(&own_inf,0,sizeof(own_inf));

     own_inf.sin_family = AF_INET;
     own_inf.sin_port   = htons(8888);
     own_inf.sin_addr.s_addr = htonl(INADDR_ANY);

    //UDP需要bind才能接收    
     if(bind(sock_fd,(struct sockaddr*)&own_inf,sizeof(own_inf)) == -1)
     {
        perror("bind...");
        return -1;
     }

    char msg[MSG_LEN] = "\0";
     while(1)
     {
        
        if(recvfrom(sock_fd,msg,sizeof(msg),0,NULL,NULL) == -1)
        {
            perror("recvfrom...");
            return -1;
        }
        printf("%s\n",msg);

     }

    close(sock_fd);
    return 0;
}
posted @ 2024-06-07 01:04  Jiangson  阅读(504)  评论(0编辑  收藏  举报