linux网络编程之广播详细代码及文档说明 -,Linux网络编程之广播

1.概念

前面介绍的TCP,UDP都是单播方式,即一对一.而广播是一台主机向局域网内的所有主机发送数据。这时,同一网段的所有主机都能接收到数据。发送广播包的步骤大致如下:

(1)确定一个发送广播的接口,如eth0

(2)确定广播的地址,通过ioctl函数,请求码设置为SIOCGIFBRDADDR得到广播的地址

(3)使用这个广播地址进行广播

由于TCP协议是端到端的协议,在通信之前,必须建立连接,三次握手之后才能发送数据。而广播是一对多的通信,所以TCP不支持广播。在局域网内,广播通常用来探测服务器。

2. 探测服务器实例

这个例子通过在局域网内发送广播包,收到广播包的服务器,应答主机。这样,就能够探测到局域网内的服务器。

主机:

/**

客户端实现广播

**/

#define IP_FOUND "IP_FOUND"

#define IP_FOUND_ACK "IP_FOUND_ACK"

#define IFNAME "eth0"

#define MCAST_PORT 9999

int main(int argc,char*argv[]){

int ret=-1;

int sock=-1;

int so_broadcast=1;

struct ifreq ifr;

struct sockaddr_in broadcast_addr;//广播地址

struct sockaddr_in from_addr;//服务端地址

int from_len=sizeof(from_addr);

int count=-1;

fd_set readfd;//读文件描述符集合

char buffer[1024];

struct timeval timeout;

timeout.tv_sec=2;//超时时间为2秒

timeout.tv_usec=0;

sock=socket(AF_INET,SOCK_DGRAM,0);//建立数据报套接字

if(sock<0){

printf("HandleIPFound:sock init error\n");

return;

}

//将使用的网络接口名字复制到ifr.ifr_name中,由于不同的网卡接口的广播地址是不一样的,因此指定网卡接口

strncpy(ifr.ifr_name,IFNAME,strlen(IFNAME));

//发送命令,获得网络接口的广播地址

if(ioctl(sock,SIOCGIFBRDADDR,&ifr)==-1){

perror("ioctl error");

return;

}

//将获得的广播地址复制到broadcast_addr

memcpy(&broadcast_addr,&ifr.ifr_broadaddr,sizeof(struct sockaddr_in));

//设置广播端口号

printf("broadcast IP is:%s\n",inet_ntoa(broadcast_addr.sin_addr));

broadcast_addr.sin_family=AF_INET;

broadcast_addr.sin_port=htons(MCAST_PORT);

//默认的套接字描述符sock是不支持广播,必须设置套接字描述符以支持广播

ret=setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&so_broadcast,sizeof(so_broadcast));

//发送多次广播,看网络上是否有服务器存在

int times=10;

int i=0;

for(i=0;i //广播发送服务器地址请求

timeout.tv_sec=2;//超时时间为2秒

timeout.tv_usec=0;

ret=sendto(sock,IP_FOUND,strlen(IP_FOUND),0,(struct sockaddr*)&broadcast_addr,sizeof(broadcast_addr));

if(ret==-1){

continue;

}

//文件描述符清0

FD_ZERO(&readfd);

//将套接字文件描述符加入到文件描述符集合中

FD_SET(sock,&readfd);

//select侦听是否有数据到来

ret=select(sock+1,&readfd,NULL,NULL,&timeout);

switch(ret){

case -1:

break;

case 0:

printf("timeout\n");

break;

default:

//接收到数据

if(FD_ISSET(sock,&readfd)){

count=recvfrom(sock,buffer,1024,0,(struct sockaddr*)&from_addr,&from_len);//from_addr为服务器端地址

printf("recvmsg is %s\n",buffer);

if(strstr(buffer,IP_FOUND_ACK)){

printf("found server IP is:%s\n",inet_ntoa(from_addr.sin_addr));

//服务器端的发送端口号

printf("Server Port:%d\n",htons(from_addr.sin_port));

}

return;

}

break;

}

}

return;

}

服务器:

/**

广播服务器端代码

**/

#define IP_FOUND "IP_FOUND"

#define IP_FOUND_ACK "IP_FOUND_ACK"

#define PORT 9999

int main(int argc,char*argv[]){

int ret=-1;

int sock;

struct sockaddr_in server_addr;//服务器端地址

struct sockaddr_in from_addr;//客户端地址

int from_len=sizeof(struct sockaddr_in);

int count=-1;

fd_set readfd;//读文件描述符集合

char buffer[1024];

struct timeval timeout;

timeout.tv_sec=2;

timeout.tv_usec=0;

sock=socket(AF_INET,SOCK_DGRAM,0);//建立数据报套接字

if(sock<0){

perror("sock error");

return;

}

memset((void*)&server_addr,0,sizeof(struct sockaddr_in));

server_addr.sin_family=AF_INET;

server_addr.sin_addr.s_addr=htons(INADDR_ANY);

server_addr.sin_port=htons(PORT);

//将地址结构绑定到套接字上./

ret=bind(sock,(struct sockaddr*)&server_addr,sizeof(server_addr));

if(ret<0){

perror("bind error");

return;

}

while(1){

timeout.tv_sec=2;

timeout.tv_usec=0;

//文件描述符集合清0

FD_ZERO(&readfd);

//将套接字描述符加入到文件描述符集合

FD_SET(sock,&readfd);

//select侦听是否有数据到来

ret=select(sock+1,&readfd,NULL,NULL,&timeout);//侦听是否可读

printf("ret=%d\n",ret);

switch(ret){

case -1://发生错误

break;

case 0://超时

printf("timeout\n");

break;

default:

if(FD_ISSET(sock,&readfd)){

count=recvfrom(sock,buffer,1024,0,(struct sockaddr*)&from_addr,&from_len);//接收客户端发送的数据

//from_addr保存客户端的地址结构

if(strstr(buffer,IP_FOUND)){

//响应客户端请求

//打印客户端的IP地址

printf("Client IP is%s\n",inet_ntoa(from_addr.sin_addr));

//打印客户端的端口号

printf("Client Send Port:%d\n",ntohs(from_addr.sin_port));

memcpy(buffer,IP_FOUND_ACK,strlen(IP_FOUND_ACK)+1);

count=sendto(sock,buffer,strlen(buffer),0,(struct sockaddr*)&from_addr,from_len);//将数据发送给客户端

}

return;

}

break;

}

}

return;

}

说明: 由于默认的套接字是不支持广播的,所以必须设置套接字选项(setsockopt)来支持广播。接口的广播地址通过ioctl函数得到。广播是基于UDP协议的。MAC地址是FF:FF:FF:FF:FF:FF.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/442877.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

求出该数组中特定元素的和,特定元素是指个位和十位不包含7的偶数。

package Day05;/*** 4.* 分析以下需求&#xff0c;并用代码实现&#xff1a;* (1).定义一个int类型的一维数组&#xff0c;内容为{171,72,19,16,118,51,210,7,18}* (2).求出该数组中特定元素的和&#xff0c;特定元素是指个位和十位不包含7的偶数。*/ public class Day05_Demo0…

linux实现自动互信,Linux 使用shell脚本实现自动SSH互信功能

说假设有一个1000台节点的Hadoop集群&#xff0c;要配置节点之间的SSH免密码登录&#xff0c;该如何用shell脚本实现&#xff1f;#!/bin/expect#循环1000台机器的IP地址&#xff0c;生成密钥文件authorized_keysfor ip in {cat ip.list}dossh user$ip ssh-keygen -t rsa &…

在编程竞赛中,有6个评委为参赛的选手打分,分数为0-100的整数分。 * (静态初始化一个数组,在数组中随意写入6个分数) 选手的最后得分为: * 去掉一个最高分和一个最低分后 的4个评委平均值。

package Day05;/*** 5、* 需求&#xff1a;在编程竞赛中&#xff0c;有6个评委为参赛的选手打分&#xff0c;分数为0-100的整数分。* &#xff08;静态初始化一个数组&#xff0c;在数组中随意写入6个分数&#xff09; 选手的最后得分为&#xff1a;* 去掉一个最高分和一个最低…

linux系统基础与应用,Linux操作系统:基础、原理与应用

《Linux操作系统&#xff1a;基础、原理与应用》第1部分基础篇第1章操作系统概述/31.1认识操作系统31.1.1操作系统的概念31.1.2操作系统的功能41.2操作系统的发展与现状51.2.1操作系统的发展51.2.2操作系统的分类与现状71.3Linux操作系统概述101.3.1Linux的发展背景与历史101.3…

兔子算法题

package Day05;/*** 6、* 兔子过三个月会成老兔子&#xff0c;第四个月开始老兔子每月都会生一个小兔子* 需求&#xff1a;有一对兔子&#xff0c;从出生起后第3个月起每个月都生一对兔子&#xff0c;* 小兔子长到第三个月后每个月又生一对兔子&#xff0c;* 假如兔子都不死&am…

linux 挂载san存储,新手看招:Linux操作系统下挂载SAN资源

在存储设备上配置好SAN资源后&#xff0c;操作Linux主机服务器1.安装iSCSI驱动程序&#xff1b;2.Linux主机安装iSCSI Initiator&#xff1b;3.配置iSCSI Inititor&#xff0c;主要是IP地址和InitiatorName&#xff0c;这一步得重启进程&#xff1b;#vi /etc/iscsi.confDiscove…

要求将数组中的0项去掉,将不为0的值存入一个新的数组,

package Day05;/*** 7、* 现在有如下一个数组&#xff1a;* int oldArr[]{1,3,4,5,0,0,6,6,0,5,4,7,6,7,0,5};* 要求将以上数组中的0项去掉&#xff0c;将不为0的值存入一个新的数组&#xff0c;*/ public class Day07_Demo07 {public static void main(String[] args) {int ol…

ccs7调试linux,【图片】【吧主帖】在LINUX(ubuntu)系统下装CCSv6方法(原创)【dsp吧】_百度贴吧...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼首先说下我的系统&#xff1a;系统&#xff1a; Ubuntu14.04.1 (AMD64bit)目标板&#xff1a;三兄弟嵌入式F28335旗舰板仿真器&#xff1a;三兄弟嵌入式XDS100V3仿真器CCS版本&#xff1a;CCS v6 linux版 32bitLinux系统必须库&…

遍历这些字符串,如果字符串没有包含数字的, * 就将字符串中的小写字母转成大写字母并打印字符串

package Day08;import java.util.Scanner;/*** 有如下字符串:"12ab","java","cd","Server78"* 遍历这些字符串&#xff0c;如果字符串没有包含数字的&#xff0c;* 就将字符串中的小写字母转成大写字母并打印字符串*/ public class Da…

湘潭大学-软件工程-选择判断题复习

说明 期末考试单选题和判断题占30分&#xff0c;单选20&#xff0c;判断10分 单选题 选错误的 B依靠松散组合的互联网大众是无法开发出高质量软件产品的 D、所有命名都应尽量使用缩写 C、采用团队的组织方式 D、软件需求一旦确定就不允许变化 以下哪一项是通过运行程序…

大学c语言编程模板,c语言编程模板

《c语言编程模板》由会员分享&#xff0c;可在线阅读&#xff0c;更多相关《c语言编程模板(8页珍藏版)》请在人人文库网上搜索。1、单片机C语言编程模板(基础模板) 程序开始处的程序说明 /* * 年 月曰 程序名&#xff1a; 编写人&#xff1a; 编写时间: 硬件支持: 接口说明: /*…

遍历strs数组,并判断数组中每一个元素的长度, * 将长度为偶数的元素和长度为奇数的元素分别存放在两个集合中,

package Day08;import java.util.ArrayList;/*** 二* 字符串数组strs中包含字符串{"12","345","6789","1","123","4567"}&#xff0c;* 创建2个ArrayList集合&#xff0c;* 遍历strs数组&#xff0c;并判断数组中…

c语言函数大全语法下载,C语言函数大全(语法).doc

C语言函数大全(语法)函数名: abort功 能: 异常终止一个进程用 法: void abort(void);程序例:#include #include int main(void){printf("Calling abort()\n");abort();return 0; /* This is never reached */}函数名: abs功 能: 求整数的绝对值用 法: int abs(int i)…

c语言 增删查 案例,C语言实现单链表的增删查改

#include#include#include"linklist.h"#define Test_Header printf("\n-----%s-----\n",__FUNCTION__);//初始化函数void linklistInit(LinkNode **head){*head NULL;}//创建新节点函数LinkNode *CreateNode(LType value){//为新节点申请空间LinkNode *ne…

模拟注册用户,按照以下要求实现相关功能:

package Day08;import java.util.Scanner;/*** 模拟注册用户&#xff0c;按照以下要求实现相关功能&#xff1a;* a. 提示用户在控制台输入手机号码&#xff0c;并接收。* b. 判断用户输入的是否都是手机号码(11位纯数字),* 如果不是手机号码,则提示用户“注册用户失败”。* c.…

FileWriter写入和Scanner录入的简单操作

import java.io.*; import java.util.Scanner;/*** 用户录入用户名和密码&#xff0c;存储到文件中&#xff0c;* 用户名和密码独占一行*/ public class Write {public static void main(String[] args) throws IOException {FileWriter fw new FileWriter("IoFile\\a.tx…

c语言实验题数组逆序,【C语言】利用栈将数组中字符串逆序

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include"stdio.h"#include"stdlib.h"#define STACK_INIT_SIZE 100#define STACKINCREMENT 10typedef struct{char *base;char *top;int stacksize;}SqStack;main(){SqStack S;char a[4];int i;InitStack(&…

IO字节缓冲流的最简单读写源码

import java.io.*;public class mode4 {public static void main(String[] args) throws IOException {//利用缓冲流去拷贝文件//创建一个字节缓冲输入流//在底层默认创建了一个长度为8192的字节数组BufferedInputStream bis new BufferedInputStream(new FileInputStream(&qu…

c语言运算符ppt,C语言知识学习运算符.ppt

C语言知识学习运算符.ppt 第三章,C语言运算符,回顾,变量和常量的含义 熟悉基本数据类型 - int、char、float 和 double 使用算术运算符 理解类型转换 熟练使用 scanf 和 printf 函数,课程目标,算术运算符 增量运算符 逻辑运算符 关系运算符 按位运算符 C的特殊运算符 --“” “…

java用数组实现随机不重复抽奖

import java.util.Random;/*** 用奖池随机抽奖*/ public class mode2 {public static void main(String[] args) {int[] arr {888, 588, 10000, 1000, 2}; //奖池int[] arr1 new int[arr.length]; //一已经中奖的奖池int intr;//用于接收随机数int count 0;//用于已经中奖…