对udp进行简单认识

认识udp

udp:用户数据报协议
提供面向事务的简单不可靠信息传送服务;
udp不提供数据包分组、组装和不能对数据包进行排序。
udp位于传输层。

udp的可靠性由应用层负责。
常用的UDP端口号有:53(DNS)、69(TFTP)、161(SNMP);
使用UDP协议包括:TFTP、SNMP、NFS、DNS、BOOTP。

udp编程接口

#include <sys/types.h>          
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

int socket(int domain, int type, int protocol);

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

uint16_t htons(uint16_t hostshort);

in_addr_t inet_addr(const char *cp);

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

udp编程方案

1:UDP单播,一方发送,一方接收

直接创建udp通信socket,使用sendto向指定的地址发送消息。
接收端也是创建udp通信socket,绑定ip和端口,用recvfrom进行接收。

2:UDP单播,使用多线程实现,可以发送和接收,双方通信。

以上实现的例子,无法实现双工通信。
可以采用多线程的方法,使双方可以同时发送和接收。
主线程实现发送,专门的线程实现接收和处理。

3:UDP单播,使用io多路复用实现,双方通信。

采用io多路复用select对端口进行监听,可读时触发接收,需要写时触发发送(标准输入加入select)。

4:组播,接收端加入到组中,可以给该组发消息,都能收到。

1:认识组播

理解: 加入一个组中,有ip和端口号,往组中对应的端口发消息,该组中所有监听了该端口的程序都可以收到消息。
注意:ip和端口号加入该组中,发送时往该组中对应的端口中发消息,组内监听该端口号的才能收到。

2:使用组播地址

需要使用组播地址 224.0.0.0 ---- 239.255.255.255如下:

1: 组播组可以是永久的也可以是临时的。组播组地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发生变化。永久组播组中成员的数量都可以是任意的,甚至可以为零。那些没有保留下来供永久组播组使用的ip组播地址,可以被临时组播组利用。
2: 224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;
3: 224.0.1.0~224.0.1.255是公用组播地址,可以用于Internet;
4: 224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;
5: 239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效

3:组播编程

1: 需要设置组播属性,进行发送:

struct in_addr opt;
// 将组播地址初始化到这个结构体成员中
inet_pton(AF_INET, "239.0.1.10", &opt.s_addr);
setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &opt, sizeof(opt));

2:加入到组播中,进行接收:

// 加入到多播组
struct ip_mreqn opt;
// 要加入到哪个多播组, 通过组播地址来区分
inet_pton(AF_INET, "239.0.1.10", &opt.imr_multiaddr.s_addr);
opt.imr_address.s_addr = INADDR_ANY;
opt.imr_ifindex = if_nametoindex("ens33");
setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &opt, sizeof(opt));

struct ip_mreq zu = {0};
zu.imr_multiaddr.s_addr = inet_addr(argv[1]);  //设置组播地址
zu.imr_interface.s_addr = inet_addr("0.0.0.0");  
int ret = setsockopt(udp_socket_fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &zu, sizeof(zu));

5:广播,给XXX.XXX.XXX.255广播地址端口发消息,该网段所有监听了该端口的接收端都能实现接收。

1:认识dup广播

往某个网段,xxx端口发送消息,则该网段所有监听了该端口的都能收到消息。

查询网段,可以用ifconfig命令: broadcast 对应的字段

hlp@hlp:~/Documents/AT_command/linux_port$ ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.11.144  netmask 255.255.255.0  broadcast 192.168.11.255
        inet6 fe80::7aaf:9514:497c:6cdf  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:8a:a9:fa  txqueuelen 1000  (Ethernet)
        RX packets 179772  bytes 98624983 (98.6 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 231502  bytes 81310878 (81.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 299314  bytes 20306394 (20.3 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 299314  bytes 20306394 (20.3 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

2:udp广播编程

发送端,需要设置广播模式,然后往广播地址中发消息:
nt on = 1;
int ret = setsockopt(udp_socket_fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));

接收端正常接收就好。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值