多播/广播

多播

多播组地址:D类IP(具体的还没学)

  1. 发送方设置TTL,接收方设置所在多组播组IP

setsockopt,IPPROTO_IP层选项:

IP_MULTICAST_TTL:生存时间(time to live):组播传送距离

IP_ADD_MEMBERSHIP:加入组播

  • 多播基于UDP协议完成,对面1000个用户,不需要像TCP建立1000个连接,不需要像UDP1000次数据传输,多播发送一次,由路由器完成包的复制

发送方:./news_sender 224.2.2.2 9190

#include <me.h>

#define TTL 64
#define BUF_SIZE 30

int main(int argc,char *argv[])
{
  int send_sock;
  struct sockaddr_in mul_adr;
  int time_live = TTL;
  if (argc != 3)
  {
    printf("Usage: %s <GroupIp> <PORT> \n",argv[0]);
    exit(1);
  }
  //设置发送方socket,以及TTL 
  send_sock = socket(AF_INET,SOCK_DGRAM,0);
  memset(&mul_adr,0,sizeof(mul_adr));
  mul_adr.sin_family = AF_INET;
  mul_adr.sin_addr.s_addr = inet_addr(argv[1]);
  mul_adr.sin_port = htons(atoi(argv[2]));
  setsockopt(send_sock,IPPROTO_IP,IP_MULTICAST_TTL,(void*)&time_live,sizeof(time_live));//设置TTL 
  
  //一次性得到消息大小发送过去
  struct stat status;
  int fd;
  fd = open("news.txt",O_RDWR);
  fstat(fd,&status);
  int len = status.st_size;
  char buf[len];
  read(fd,buf,len);

  sendto(send_sock,buf,len,0,(struct sockaddr*)&mul_adr,sizeof(mul_adr));

  close(fd);
  close(send_sock);
  return 0;
}

接收方./news_receiver 224.2.2.2 9190

#include <me.h>
#define BUF_SIZE 40

int main(int argc,char *argv[])
{
  int recv_sock;
  int str_len;
  char buf[BUF_SIZE];
  struct sockaddr_in adr;
  struct ip_mreq join_adr;
  if (argc != 3)
  {
    printf("Usage : %s <GroupIp> <PORT>\n",argv[0]);
    exit(1);
  }

  recv_sock = socket(AF_INET,SOCK_DGRAM,0);
  memset(&adr,0,sizeof(adr));
  adr.sin_family = AF_INET;
  adr.sin_addr.s_addr = htonl(INADDR_ANY);
  adr.sin_port = htons(atoi(argv[2]));

  if (bind(recv_sock,(struct sockaddr*)&adr,sizeof(adr)) == -1)
    error_handle("bind() error")

  //加入多播组 
  join_adr.imr_multiaddr.s_addr = inet_addr(argv[1]); //多播组的组IP地址 
  join_adr.imr_interface.s_addr = htonl(INADDR_ANY);  //主机的IP地址 

  setsockopt(recv_sock,IPPROTO_IP,IP_ADD_MEMBERSHIP,(void*)&join_adr,sizeof(join_adr));

  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);
    memset(&buf,0,sizeof(buf));
  }

  close(recv_sock);
  return 0;
}

广播

  1. 直接广播
  2. 本地广播 IP:255.255.255.255,给子网所有主机发送传输数据,

和多播不同的是范围

send.c

#include <me.h>
#define BUF_SIZE 30

int main(int argc,char *argv[])
{
  int send_sock;
  struct sockaddr_in broad_adr;
  FILE *fp;
  char buf[BUF_SIZE+10];
  int so_brd = 1;
  if (argc != 3)
  {
    printf("Usage : %s <Broadcast IP> <PORT>\n",argv[0]);
    exit(1);
  }

  send_sock = socket(AF_INET,SOCK_DGRAM,0);//UDP端口
  memset(&broad_adr,0,sizeof(broad_adr));
  broad_adr.sin_family = AF_INET;
  broad_adr.sin_addr.s_addr = inet_addr(argv[1]);
  broad_adr.sin_port = htons(atoi(argv[2]));

  //设置socket为广播 
  setsockopt(send_sock,SOL_SOCKET,SO_BROADCAST,(void*)&so_brd,sizeof(so_brd));
  
  if ((fp = fopen("news.txt","r")) == NULL)
    error_handle("fopen() error")

  while(!feof(fp))
  {
    fgets(buf,BUF_SIZE,fp);
    sendto(send_sock,buf,strlen(buf),0,(struct sockaddr*)&broad_adr,sizeof(broad_adr));
    char ch = fgetc(fp);
    if (ch == EOF)
      break;
    else
      sendto(send_sock,&ch,1,0,(struct sockaddr*)&broad_adr,sizeof(broad_adr));
    sleep(1);
  }
  close(send_sock);
  return 0;
}

receive.c

#include <me.h>
#define BUF_SIZE 30

int main(int argc,char *argv[])
{
  int recv_sock;
  struct sockaddr_in adr;
  int str_len;
  char buf[BUF_SIZE];
  if (argc != 2)
  {
    printf("Usage : %s <PORT> \n",argv[0]);
    exit(1);
  }

  recv_sock = socket(AF_INET,SOCK_DGRAM,0);
  memset(&adr,0,sizeof(adr));
  adr.sin_family = AF_INET;
  adr.sin_addr.s_addr = htonl(INADDR_ANY);
  adr.sin_port = htons(atoi(argv[1]));

  if (bind(recv_sock,(struct sockaddr*)&adr,sizeof(adr)) == -1)
    error_handle("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;
}

来自<<TCP/IP 网络编程 尹圣雨>>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值