linux学习之多高并发服务器篇(三)

UDP多播服务器

多播

  组播组可以是永久的也可以是临时的。组播组地址中,有一部分由官方分配的,称为永久组播组。永久组播组保持不变的是它的ip地址,组中的成员构成可以发 生变化。永久组播组中成员的数量都可以是任意的,甚至可以为零。那些没有保留下来供永久组播组使用的ip组播地址,可以被临时组播组利用。

224.0.0.0~224.0.0.255为预留的组播地址(永久组地址),地址224.0.0.0保留不做分配,其它地址供路由协议使用;  
224.0.1.0~224.0.1.255是公用组播地址,可以用于Internet;  224.0.2.0~238.255.255.255为用户可用的组播地址(临时组地址),全网范围内有效;   
239.0.0.0~239.255.255.255为本地管理组播地址,仅在特定的本地范围内有效。

ip ad

查看网卡编号

if_nametoindex

  将几台电脑分为一个组,同一个组内本身每个电脑都有自己的ip地址,同组的都有一个组号,若想把一个包发给一个组,目的ip设为组号。一对多的数据传输,在ip层存在一个组播的概念,客户端的ip地址没有意义了,客户端要接受的端口号仍然有意义,tcp或udp封装端口号,说明哪个进程接受,一般应用于UDP领域,TCP用的非常少。

   若server要发一个组播包,write(sockfd,buf,buflen);引入一个新的函数setsockopt,可以设置多层协议。

实例:

/* server.c */

#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include<net/if.h>
#include "wrap.h"
#define MAXLINE 80
#define SERV_PORT 8000
#define CLIENT_PORT 9000//客户端的端口号
#define GROUP "239.0.0.2"

int main(void)
{
    struct sockaddr_in servaddr, cliaddr;//用于IPv4的地址
    socklen_t cliaddr_len;
    int sockfd;//文件描述符
    char buf[MAXLINE];
    char str[INET_ADDRSTRLEN];//16 Bytes
    struct ip_mreqn group;
    ssize_t len;
    int i, n;
    /*构造用于UDP通信的套接字*/
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);//

    bzero(&servaddr, sizeof(servaddr));//将地址清零
    //设置地址
    servaddr.sin_family = AF_INET;/*IPv4*/
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//网络字节数,本地任意IP
    servaddr.sin_port = htons(SERV_PORT);

    bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

    /*设置组地址*/
    inet_pton(AF_INET,GROUP,&group.imr_multiaddr);
    /*本地任意IP*/
    inet_pton(AF_INET,"0.0.0.0",&group.imr_address);
    /*eth0-->编号 命令:ip ad*/
    group.imr_ifindex=if_nametoindex("eth0");

    setsockopt(sockfd,IPPROTO_IP,IP_MULTICAST_IF,&group,sizeof(group));

   /*构造client 地址 IP+端口*/
    bzero(&clientaddr, sizeof(clientaddr));//将地址清零 //设置地址
  clientaddr.sin_family = AF_INET;/*IPv4*/
  inet_pton(AF_INET,GROUP,&clientaddr.sin_addr.s_addr);
  clientaddr.sin_port=htons(CLIENT_PORT);
  printf("Accepting connections ...\n"); 

  while (1)
      {   
    fgets(buf,sizeof(buf),stdin);
    sendto(sockfd,buf,strlen(buf),0,(struct sockaddr *)&clientaddr,sizeof(clinetaddr));
     }
  close(sockfd);
   return 0;
} 

/* client.c */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include<net/if.h>
#include <netinet/in.h>
#include "wrap.h"
#define MAXLINE 4096
#define SERVER_PORT 8000
#define CLIENT_PORT 9000
#define GROUP "239.0.0.2”
int main(int argc, char *argv[])
{
          struct sockaddr_in serveraddr,localaddr;
          int confd;
          ssize_t len;
          struck ip_mreqn   group;//组播结构体
          char buf[MAXLINE];

          //1.创建一个socket
          confd=socket(AF_INET,SOCK_DGRAM,0);

         //2.初始化本地端地址
         bzero(&localaddr,sizeof(localaddr));
         localaddr.sin_family=AF_INET;
         inet_pton(AF_INET,"0.0.0.0",&localaddr.sin_addr.s_addr);
         localaddr.sin_port=htons(CLIENT_PORT);
         bind(confd,(struct sockaddr *)&localaddr,sizeof(localaddr));

          //加入多播组
          inet_pton(AF_INET,GROUP,&group.imr_multiaddr);
          inet_pton(AF_INET,"0.0.0.0",&group.imr_address);
          group.imr_ifindex=if_nametoindex("eth0");

         //设置client加入多播组
          setsockopt(confd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&group,sizeof(group));

        while(1)
        {
                 len=recvfrom(confd,buf,sizeof(buf),0,NULL,0);
                 write(STDOUT_FILENO,buf,len);
         }
         close(confd);
         return 0;

}  

其他常用函数

名字与地址转换:

过时,仅用于IPv4,线程不安全

gethostbyname  通过网址知道ip地址

gethostbyaddr    通过IP地址知道网址

getservbyname
getservbyport

根据服务器程序名字或端口号获取信息,用的不多

getaddrinfo
getnameinfo

freeaddrinfo   

趋势,可同时处理IPv4和IPv6,线程安全

套接口和地址关联

getsockname

根据accept返回的的sockfd,得到临时端口号

getpeername

根据accept返回的sockfd,得到远端链接的端口号,在exec后可以获取客户端信息

来源https://www.cnblogs.com/rainbow1122/p/7891490.html

原文地址:https://www.cnblogs.com/zzdbullet/p/9513685.html

时间: 2024-08-29 15:36:21

linux学习之多高并发服务器篇(三)的相关文章

linux学习之多高并发服务器篇(一)

高并发服务器 高并发服务器 并发服务器开发 1.多进程并发服务器 使用多进程并发服务器时要考虑以下几点: 父最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符) 系统内创建进程个数(内存大小相关) 进程创建过多是否降低整体服务性能(进程调度) server /* server.c */ #include <stdio.h> #include <string.h> #include <netinet/in.h> #include <arpa/

linux学习之高并发服务器篇(二)

高并发服务器 1.线程池并发服务器 两种模型: 预先创建阻塞于accept多线程,使用互斥锁上锁保护accept(减少了每次创建线程的开销) 预先创建多线程,由主线程调用accept 线程池 3.多路I/O转接服务器 三种模型性能分析 select模型 select用来阻塞监听4,5,6,7是否有数据传入,若7这个文件描述符有数据到达,select返回就绪文件描述符个数,若检测到7有数据接收,accept接收客户链接请求,创建一个新的文件描述符. select (1)select能监听的文件描述

Linux 高并发服务器

高并发服务器 一.多进程并发服务器 1. 实现示意图 2. 使用多进程并发服务器时要考虑以下几点: 父进程最大文件描述个数(父进程中需要close关闭accept返回的新文件描述符) 系统内创建进程个数(与内存大小相关) 进程创建过多是否降低整体服务性能(进程调度) 3. 使用多进程的方式, 解决服务器处理多连接的问题:     (1)共享 读时共享, 写时复制 文件描述符 内存映射区 -- mmap     (2)父进程 的角色是什么? 等待接受客户端连接 -- accept 有链接: 创建一

全面的高性能高并发服务器架构解决方案教程

* { font-family: "Microsoft YaHei" !important } h1 { color: #FF0 } 15套java架构师.集群.高可用.高可扩 展.高性能.高并发.性能优化.Spring boot.Redis.ActiveMQ.Nginx.Mycat.Netty.Jvm大型分布 式项目实战视频教程 视频课程包含: 高级Java架构师包含:Spring boot.Spring  cloud.Dubbo.Redis.ActiveMQ.Nginx.Mycat

为一个支持GPRS的硬件设备搭建一台高并发服务器用什么开发比较容易?

高并发服务器开发,硬件socket发送数据至服务器,服务器对数据进行判断,需要实现心跳以保持长连接. 同时还要接收另外一台服务器的消支付成功消息,接收到消息后控制硬件执行操作. 查了一些资料,java的netty,go,或者是用C/C++不知道该用哪个,想问一下哪个比较适合,学习更容易一些. 为一个支持GPRS的硬件设备搭建一台高并发服务器用什么开发比较容易? >> golang 这个答案描述的挺清楚的:http://www.goodpm.net/postreply/golang/101000

高并发服务器开发与配置

一.4大具有代表性的并发模型及其优缺点        4大具有代表性的并发模型:Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型,select模型和poll模型.Epoll模型.        Apache(PPC)模型和TPC模型是最容易理解的,Apache模型在并发上是通过多进程实现的,而TPC模型是通过多线程实现的,但是这2种方式在大量进程/线程切换时会造成大量的开销.        select模型是通过

JAVA NIO non-blocking模式实现高并发服务器

JAVA NIO non-blocking模式实现高并发服务器 分类: JAVA NIO2014-04-14 11:12 1912人阅读 评论(0) 收藏 举报 目录(?)[+] Java自1.4以后,加入了新IO特性,NIO. 号称new IO. NIO带来了non-blocking特性. 这篇文章主要讲的是如何使用NIO的网络新特性,来构建高性能非阻塞并发服务器. 文章基于个人理解,我也来搞搞NIO.,求指正. 在NIO之前 服务器还是在使用阻塞式的java socket. 以Tomcat最

【Linux学习】Ubuntu下 samba服务器搭建

1.安装samba,smbfs 2.配置smb.conf文件 配置文件之前需要先备份一下需要配置的文件(养成好的习惯) 输入命令: 进入到smb.conf文件中,在文件的最后添加下列语句 保存后,退出. 3.启动服务 4.现在在samba共享的文件夹下有一下文件 然后通过windows访问共享目录,输入 \\172.16.42.6后看到共享的temp文件夹, [Linux学习]Ubuntu下 samba服务器搭建,布布扣,bubuko.com

第15章 高并发服务器编程(2)_I/O多路复用

3. I/O多路复用:select函数 3.1 I/O多路复用简介 (1)通信领域的时分多路复用 (2)I/O多路复用(I/O multiplexing) ①同一线程,通过"拨开关"方式,来同时处理多个I/O流,哪个IO准备就绪就把开关拨向它.(I/O多路复用类似于通信领域中的"时分复用") ②通过select/poll函数可以实现IO多路复用,他们采用轮询的方式来监视I/O.而epoll是对select/poll的加强,它是基于事件驱动,epoll_ctl注册事件