LINUX 网络编程 广播/组播通信
广播包
- 只可以在同一个网段传播,不可以跨网段传播
- 一个人广播 所有人都会接受到信息
- 路由器是不会转发 广播数据包
- 交换机可以转发 广播包
- 广播包的 ARP地址是全F
目地MAC地址:FF:FF:FF:FF:FF:FF
本地MAC地址:10:c1:72:25:49:5e
对方就会知道本机的MAC地址 随之返回
ARP 协议
- 局域网的MAX地址发现
- 只有两 呼应包
VLAN
- 隔离池 阻断同一个局域网的ARP通信
- 属于逻辑隔离
广播 编程
- 广播 socket必须是 帧传输SOCK_DGRAM
setsockopt() 设置选择值
int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen);
头文件 :#include
sock:将要被设置套接字
level:套接字接口类型(章节)
optname:设置的章中的哪一个节
optval: 指向包含新选项值的缓冲
optlen:缓冲 长度
返回值:成功为0
失败 -1
getsockopt()获取选择值
int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen);
setsockopt 接口类型(章节)
level指定控制套接字的层次
- SOL_SOCKET: 通用套接字选项
- IPPROTO_IP:IP选项
- IPPROTO_TCP: TCP选项
optname 章节中的哪一个节
SOL_SOCKET 中的选项
| 参数 | 含义 | 类型 |
|---|---|---|
| SO_BROADCAST | 允许发送广播数据 | int |
| SO_DEBUG | 允许调试 | int |
| 0 | 禁止发送广播 | int |
| 1 | 允许发送广播 | int |
| SO_LINGER | 延迟关闭连接 | struct linger |
| SO_RCVTIMEO | 接收超时 | struct linger |
| SO_SNDTIMEO | 发送超时 | struct linger |
| SO_TYPE | 获得套接字类型 | int |
| SO_REUSEADDR | 允许套接口和一个已在使用中的地址捆绑 | bool |
| SO_RCVBUF | 接收缓冲区大小 | int |
IPPROTO_IP
| 参数 | 含义 | 类型 |
|---|---|---|
| IP_HDRINCL | 自定义数据包 | int |
| IP_OPTINOS | IP首部选项 | int |
| IP_TOS | 服务类型 | int |
| IP_TTL | 生存时间 | int |
| IP_ADD_MEMBERSHIP | 用于加入多播组 | struct ip_mreq |
| IP_DROP_MEMBERSHIP | 用于退出多播组 | struct ip_mreq |
- IP_ADD_MEMBERSHIP / IP_DROP_MEMBERSHIP
该选项用于将指定网络接口上的套接口加入IP 多播组,此套接口必须是AF_INET 地址族并且类型为SOCK_DGRAMstruct ip_mreq {struct in_addr imr_multiaddr ;struct in_addr imr_interface;};ip_mreq.imr_multiaddr.s_addr 组播IP地址ip_mreq.in_interface.s_addr 接口的本地IP地址
IPPRO_TCP
| TCP_MAXSEG | TCP最大数据段的大小 |
|---|---|
| TCP_NODELAY | 不使用Nagle算法 |
- send Breadcast
#include <stdio.h>#include <sys/socket.h>#include <errno.h>#include <stdlib.h>#include <string.h>#include <arpa/inet.h>#include <unistd.h>int main(int argc, char* argv[]){int ser;/* 必须是数据报文形式传输*/ser = socket(AF_INET, SOCK_DGRAM,0);if (ser == -1) {perror("Socket Error !!");exit(1);}printf("Scoket OKEY !!\n");fflush(stdout);int _e = 1;int _f = setsockopt(ser, SOL_SOCKET, SO_BROADCAST, &_e, sizeof(_e));if (_f == -1) {perror("Sersockopt Error !!");exit(1);}struct sockaddr_in seraddr;seraddr.sin_family = AF_INET;seraddr.sin_port = htons(8888);seraddr.sin_addr.s_addr = inet_addr("192.168.1.255");//seraddr.sin_addr.s_addr = htonl(INADDR_ANY);int addr_len = sizeof(struct sockaddr);char buf[20];strcpy(buf, "hello message!");int len = sendto(ser, buf, sizeof(buf), 0,(struct sockaddr*)(&seraddr), addr_len);if (len < 0) {perror("sendto Error!!");exit(1);}printf("sendto or YES send /n");fflush(stdout);exit(0);}
组播包
源主机只发送一份数据 , 是属于该组的成员,都可以接收到一份原主机发送的数据的拷贝 ,以外的人接收不到
- 组播包的IP段:224.0.0.1 ~ 239.255.255.255
- 设置加入组
struct ip_mreq 结构体
imr_multiaddr :组 IP
imr_interface :接口的本地IP地址
主机进行解析域名
当主机拿到一个域名时 会先去 /etc/hosts 文件中去匹配有没有对应的IP地址 如果有就使用就不会往下走,没有就会到DNS上去寻找
/etc/resolv.config 这个是DNS 服务器地址文件
当没有在/etc/hosts文件中找到域名IP地址就会去/etc/resolv.config寻找DNS服务器的地址 在向DNS请求域名IP地址
gethostbyname 域名解析函数
- 参数1: 域名
- 返回值 :struct hostent
struct hostent {const char *h_name; // 主机的官方名称char **h_aliases; // 主机备选名称short h_addrtype; // 主机返回地址类型short h_length; // 地址长度char **h_addr_list; // IP列表};
