博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【linux高级程序设计】(第十五章)UDP网络编程应用 2
阅读量:6569 次
发布时间:2019-06-24

本文共 2763 字,大约阅读时间需要 9 分钟。

UDP广播通信

单播:一对一,TCP和UDP均可完成

广播:只能UDP完成。广播时发送方只发送一个数据包,但是网络上的交换机默认转发广播数据包到所有端口。路由器默认不转发任何广播数据包。故广播在局域网范围内。

组播:只有UDP可以完成。发送消息到同一个组播组的主机。视频电话、视频会议多采用。

 

广播IP地址:主机号全1。网络号正常

广播MAC地址:全1,即FF:FF:FF:FF:FF:FF

 

广播数据帧格式

处理过程:

网卡驱动程序对比自己的MAC地址与目的MAC地址,发现是广播MAC地址,统一接收并交给OS(IP层)。

IP层判断IP地址与自己是否一致。发现为IP地址为当前网段的广播地址,交给传输层

传输层根据端口,如果有对应的端口交给应用程序处理。否则丢弃数据包。

不管主机是否有进程接收广播消息,广播消息一定会被网卡收到并交个操作系统处理。会造成网络主机负担。

 

设置socket可以发送广播消息

int yes = 1;setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes));

接收端绑定地址信息时,需要制定接收任意地址信息的数据包。

 

例子:

发送端广播一段信息,接收端接收。

注意:setsockopt为广播的目的应该是告知MAC地址为FF:FF:FF:FF:FF:FF 而广播的IP地址需要我们自己写上。即(网络号:全1主机号)。通过ifconfig获取。

 

发送端

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv){ struct sockaddr_in s_addr; int sock; int addr_len; int len; char buff[128]; int yes; //UDP 创建socket if((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket"); exit(EXIT_FAILURE); } else { printf("create socket.\n\r"); } //设置socket为可发送广播消息 yes = 1; setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &yes, sizeof(yes)); s_addr.sin_family = AF_INET; s_addr.sin_port = htons(7838); if(argv[1]) { s_addr.sin_addr.s_addr = inet_addr(argv[1]); //参数1 广播地址 } else { printf("input sever ip!\n"); exit(0); } addr_len = sizeof(s_addr); strcpy(buff, "hello message"); //发送消息 len = sendto(sock, buff, strlen(buff), 0, (struct sockaddr *)&s_addr, addr_len); if(len < 0) { printf("\n\rsend error.\n\r"); exit(EXIT_FAILURE); } printf("send success.\n\r"); return 0;}

接收端

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int argc, char **argv){ struct sockaddr_in s_addr; struct sockaddr_in c_addr; int sock; socklen_t addr_len; int len; char buff[128]; //创建socket UDP if((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket"); exit(EXIT_FAILURE); } else { printf("create socket.\n\r"); } memset(&s_addr, 0, sizeof(struct sockaddr_in)); s_addr.sin_family = AF_INET; s_addr.sin_port = htons(7838); s_addr.sin_addr.s_addr = INADDR_ANY; //绑定IP地址 if((bind(sock, (struct sockaddr *)&s_addr, sizeof(s_addr))) == -1) { perror("bind"); exit(EXIT_FAILURE); } else { printf("bind address to socket.\n\r"); } addr_len = sizeof(c_addr); while(1) { //阻塞方式接收数据 len = recvfrom(sock, buff, sizeof(buff) - 1, 0, (struct sockaddr *)&c_addr, &addr_len); if(len < 0) { perror("recvfrom"); exit(EXIT_FAILURE); } buff[len] = '\0'; printf("recive come from %s:%d message:%s\n\r", inet_ntoa(c_addr.sin_addr), ntohs(c_addr.sin_port), buff); } return 0;}

 

转载地址:http://ybpjo.baihongyu.com/

你可能感兴趣的文章
【Unity3D】资源对象、预设、查找对象、组合模式等知识点
查看>>
iOS开发UI篇—实现UITableview控件数据刷新
查看>>
linux命令
查看>>
chrome取消安全模式
查看>>
团队-象棋游戏-设计文档
查看>>
hibernate Expression详解
查看>>
HTTP长连接和短连接以及推送服务原理(转)
查看>>
问卷设计入门
查看>>
input子系统分析之三:驱动模块
查看>>
jquery 选择时间(小时)区间(四)
查看>>
jquery 选择时间(小时)区间(二)
查看>>
WebService的编写与调用
查看>>
(模板)字符串哈希
查看>>
input:focus
查看>>
java中String,int,Integer,char、double类型转换
查看>>
Hdoj 2544
查看>>
nginx转发端口路由器再转发
查看>>
在eclipse里的 flex 没有可视化的编辑
查看>>
python 列出出当前目录及所有子目录下的文件
查看>>
RabbitMQ错误检查
查看>>