网络编程、广播、组播、数据库sqlite3

二、广播

1、广播特点

多点通讯 全网广播:255.255.255.255 容易造成网络风暴 子网广播:x.x.x.255 只允许数据报套接字操作 /*设置网络允许广播*/ int val = 1 setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(int));

2、广播发送端流程

  1. 创建数据报(udp)套接字

  2. 设置套接字属性允许广播

  3. 设置接收方IP为广播地址

  4. 设置广播端口号

  5. 发送数据

3、广播发送示例 ​

/*========================================================
*   > 文 件 名 称: send.c
*   > 创  建  者: 清风徐来 
*   > 邮    箱: zhangsl_cd@hqyj.com
*   > 创 建 时 间: 2020年08月24日 星期一 09时19分43秒
==========================================================*/
​
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/ip.h>
​
#define N 64
#define PORT 8888
int main()
{
    int fd, val = 1;
    if(-1 == (fd = socket(AF_INET, SOCK_DGRAM, 0))){
        perror("socket");
        exit(-1);
    }
​
    /*设置允许广播*/
    if(-1 == setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(int))){
        perror("setsockopt");
        exit(-1);
    }
​
    /*设置接收方的IP和PORT*/
    struct sockaddr_in sddr, cddr;
    sddr.sin_family      = AF_INET;
    sddr.sin_port        = htons(PORT);
    sddr.sin_addr.s_addr = inet_addr("192.168.10.255");
​
    char buf[N] = {0};
    int len  = sizeof cddr;
    while(1){
        printf("send> ");fflush(stdout);
        fgets(buf, N, stdin);
        if(-1 == sendto(fd, buf, N-1, 0, (void *)&sddr, sizeof(sddr))){
            perror("sendto");
            exit(-1);
        }
        if(0 == strncasecmp(buf, "quit", 4)){
            break;
        }
        bzero(buf, N);
        if(-1 == recvfrom(fd, buf, N, 0, (void *)&cddr, &len)){
            perror("recvfrom");
            exit(-1);
        }
        printf("recv> %s\n", buf);
    }
    close(fd);
}

三、组播(多播)

1、组播(多播)特点

属于多点通讯。

单播是一对一,广播是发送给所有主机,带宽占用大容易出现网络风暴,而多播是折中处理,只有加入多播组才能接收多播数据 组播IP:224.0.0.0 - 239.255.255.255 属于D类地址

组播通信需要先创建多播组(发送方和接收方任意一方创建即可)

创建/加入多播组,设置网络属性
    创建:IP_MULTICAST_IF
        struct ip_mreqn
        {
            struct in_addr imr_multiaddr; /* IP多点传送组地址 */
            struct in_addr imr_address; /* 本地接口的IP地址 */
            int imr_ifindex; /* 接口索引 */ //即网卡编号
        };
        imr_ifindex:
            #include <net/if.h>
            unsigned if_nametoindex(const char *ifname); //自动获取指定设备的索引号
    
    加入:IP_ADD_MEMBERSHIP
        struct ip_mreqn
        {
            struct in_addr imr_multiaddr; /* IP多点传送组地址 */
            struct in_addr imr_address; /* 本地接口的IP地址 */
            int imr_ifindex; /* 接口索引 */
        };
        imr_ifindex:
            #include <net/if.h>
            unsigned if_nametoindex(const char *ifname); //自动获取指定设备的索引号

2、组播发送方流程

  1. 创建数据报套接字(udp)

  2. 接收方地址定为组播地址

  3. 设置端口号

  4. 发送数据

3、组播发送方示例

/*========================================================
*   > 文 件 名 称: send.c
*   > 创  建  者: 清风徐来 
*   > 邮    箱: zhangsl_cd@hqyj.com
*   > 创 建 时 间: 2020年08月24日 星期一 10时35分12秒
==========================================================*/
​
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/ip.h>
​
#include <net/if.h>
​
#define N 64
#define RPORT 8888
​
int main()
{
 int fd = socket(AF_INET, SOCK_DGRAM, 0);
 if(-1 == fd){
     perror("socket");
     exit(-1);
 }
 /*填充ip_mreqn结构体*/
 struct ip_mreqn mreq;
 mreq.imr_multiaddr.s_addr = inet_addr("224.3.3.3");
 mreq.imr_address.s_addr   = inet_addr("0.0.0.0"); //
 mreq.imr_ifindex          = if_nametoindex("eth0");
 /*创建多播组*/
 if(-1 == setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &mreq, sizeof(mreq))){
     perror("setsockopt");
     exit(-1);
 }
​
 /*填充发送接收方IP和PORT*/
 struct sockaddr_in sddr;
 sddr.sin_family         = AF_INET;
 sddr.sin_port           = htons(RPORT); //RPORT is define :8888
 sddr.sin_addr.s_addr    = inet_addr("224.3.3.3"); //向多播组发送
​
 char buf[N] = {0};
 while(1){
     printf("send> ");fflush(stdout);
     fgets(buf, N, stdin);
     if(-1 == sendto(fd, buf, N, 0, (void *)&sddr, sizeof(sddr))){
         perror("sendto");
         exit(-1);
     }
     if(!strncasecmp(buf, "quit", 4)){
         break;
     }
 }
}

4、组播接收方流程

  1. 创建数据报套接字(udp)

  2. 加入多播组

  3. 绑定IP地址(加入组的组IP或"0.0.0.0")和端口号

  4. 等待接收数据

5、组播接收方示例

/*========================================================
*   > 文 件 名 称: send.c
*   > 创  建  者: 清风徐来 
*   > 邮    箱: zhangsl_cd@hqyj.com
*   > 创 建 时 间: 2020年08月24日 星期一 10时35分12秒
==========================================================*/
​
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/ip.h>
​
#include <net/if.h>
​
#define N 64
#define RPORT 8888
​
int main()
{
 int fd = socket(AF_INET, SOCK_DGRAM, 0);
 if(-1 == fd){
     perror("socket");
     exit(-1);
 }
 /*填充ip_mreqn结构体*/
 struct ip_mreqn mreq;
 mreq.imr_multiaddr.s_addr = inet_addr("224.1.3.3");
 mreq.imr_address.s_addr   = inet_addr("0.0.0.0"); //
 mreq.imr_ifindex          = if_nametoindex("eth0");
 /*加入多播组*/
 if(-1 == setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))){
     perror("setsockopt");
     exit(-1);
 }
​
 /*填充发送接收方IP和PORT*/
 struct sockaddr_in sddr, cin;
 sddr.sin_family         = AF_INET;
 sddr.sin_port           = htons(RPORT); //RPORT is define :8888
 sddr.sin_addr.s_addr    = inet_addr("0.0.0.0");
​
 /*绑定自己的IP和PORT*/
 if(-1 == bind(fd, (void *)&sddr, sizeof(sddr))){
     perror("bind");
     exit(-1);
 }
​
 int len = sizeof cin;
 char buf[N] = {0};
 while(1){
     if(-1 == recvfrom(fd, buf, N, 0, (void *)&cin, &len)){
         perror("sendto");
         exit(-1);
     }
     if(!strncasecmp(buf, "quit", 4)){
         break;
     }
     printf("recv> %s", buf);
 }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

clown_30

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值