15.2 广播

1. 多播即使在跨越不同网络的情况下,只要加入多播组就能接收数据。

广播只能向同一网络中的主机传输数据。与多播相同,广播也是基于UDP完成的。根据传输数据时使用的IP地址形式,广播分成2种:直接广播和本地广播

直接广播的IP地址中除了网络地址外,其余主机地址全部设置成1。如向192.12.34中的所有主机传送数据,使用地址为192.12.34.255.

本地广播使用的IP地址限定为255.255.255.255


2. 默认生成的套接字阻止广播,需要更改设置。数据通讯中使用的IP地址是与UDP示例的唯一区别。

int bcast = 1;

setsockopt(send_sock,SOL_SOCKET,SO_BROADCAST,(void *)&bcast, sizeof(bcast));

3. 示例:

sender.c

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  
#include <arpa/inet.h>  
#include <sys/socket.h>  
  
#define BUF_SIZE    30
  
void error_handling(char *message);  
  
int main(int argc, char *argv[]){  
    int send_sock;
    FILE *fp;  
    char buf[BUF_SIZE];  
    struct sockaddr_in broad_adr;
    int so_brd = 1;
  
    if(argc != 3){  
        printf("Usage : %s <group><port>\n",argv[0]);  
        exit(1);  
    }  

    send_sock = socket(PF_INET,SOCK_DGRAM,0);  
    if(send_sock == -1){  
        error_handling("socket() error");  
    }  
  
    memset(&broad_adr,0,sizeof(broad_adr));  
    broad_adr.sin_family=AF_INET;  
    broad_adr.sin_addr.s_addr=inet_addr(argv[1]);	//ip  
    broad_adr.sin_port=htons(atoi(argv[2]));  //port
  
    setsockopt(send_sock,SOL_SOCKET,SO_BROADCAST,(void *)&so_brd,sizeof(so_brd));
    if((fp = fopen("news.txt","r")) == NULL){
  	error_handling("fopen");
    }

    while(!feof(fp)){
	fgets(buf,BUF_SIZE,fp);
	sendto(send_sock,buf,strlen(buf),0,(struct sockaddr *)&broad_adr,sizeof(broad_adr));
	sleep(2);
    }
    fclose(fp);
    close(send_sock);

    return 0;  
}  
  
void error_handling(char *message){  
  
    fputs(message,stderr);  
    fputs("\n",stderr);  
    exit(1);  
}  

执行结果:

alex@alex-virtual-machine:/extra/tcpip$ ./sender 255.255.255.255 9190

receiver.c

#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
#include <unistd.h>  
#include <arpa/inet.h>  
#include <sys/socket.h>  
  
#define BUF_SIZE    30
  
void error_handling(char *message);  
  
int main(int argc, char *argv[]){  
    int recv_sock;
    int str_len;
    char buf[BUF_SIZE];  
    struct sockaddr_in adr;
      
    if(argc != 2){  
        printf("Usage : %s <port>\n",argv[0]);  
        exit(1);  
    }  

    recv_sock = socket(PF_INET,SOCK_DGRAM,0);  
    if(recv_sock == -1){  
        error_handling("socket() error");  
    }  
  
    memset(&adr,0,sizeof(adr));  
    adr.sin_family=AF_INET;  
    adr.sin_addr.s_addr=htonl(INADDR_ANY);	// ip  
    adr.sin_port=htons(atoi(argv[1]));  //port
  
    if(bind(recv_sock,(struct sockaddr *)&adr,sizeof(adr))==-1){
	error_handling("bind error");
    }

    while(1){
    	str_len = recvfrom(recv_sock,buf,BUF_SIZE-1,0,NULL,0);
	if(str_len < 0){
	    break;
	}
	buf[str_len] = 0;
	fputs(buf,stdout);
    }
    close(recv_sock);

    return 0;  
}  
  
void error_handling(char *message){  
  
    fputs(message,stderr);  
    fputs("\n",stderr);  
    exit(1);  
}  

执行结果:

alex@alex-virtual-machine:/extra/tcpip$ ./receiver 9190
int main(int argc, char *argv[]){
    int i;
    struct hostent *host;

    if(argc != 2){

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值