首页 > 其他分享 >多路复用

多路复用

时间:2024-08-30 21:03:54浏览次数:8  
标签:addr 多路复用 int ret readfds sockfd include

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sys/time.h>
#include <sys/select.h> 
int main(void)
{
     //1.创建套接字
     int  sockfd  = socket(AF_INET, SOCK_STREAM, 0);
    if( sockfd < 0)
    {
        perror("socket");
        return -1;
    }
     //2.绑定端口和地址
    struct sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_port = htons(9527);
     //转网络字节序
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
     //inet_addr("192.168.41.1");
     //网络字节序(32位整型数ip地址)
    //绑定地址为INADDR_ANY,这个个服务器程序在那个ip地址上运行就绑定那个ip地址    
     int ret = bind(sockfd, (struct sockaddr*)&addr,sizeof(addr));
    if(ret < 0)
    {
        perror("bind");
        return -1;
    }
    //3.监听
    ret  = listen(sockfd, 4);
    if(ret < 0)
    {
        perror("listen");
        return -1;
    }
     //接受连接--accept阻塞
    //接收客户端数据--recv阻塞
     //select多路复用
     fd_set readfds;
     //定义读文件描述符集合
    int  cfds[50]={0};
     //保存所有客户端的套接字
    while(1)
    {
        int maxfd = sockfd;
        //清空集合
        FD_ZERO(&readfds);
        FD_SET(sockfd,&readfds);
          //把sockfd添加到readfds集合中
          //把客户端的套接字也添加到集合中
        for(int i=0; i<50; i++)
        {
              if(cfds[i] != 0)//如果不等于0就说明这个空间存储了套接字 
           {
                FD_SET(cfds[i],&readfds);
                maxfd = maxfd>cfds[i]?maxfd:cfds[i];
            }
        }        //select用监听readfds里面的所有文件描述符,
        //如果某一个或多个描述符有响应就跳出select函数
        ret = select(maxfd+1,&readfds,NULL, NULL, NULL);
        if(ret < 0)
        {
            perror("select");
        }
        //判断是否是sockfd有数据---说明有客户端连接
        if(FD_ISSET(sockfd, &readfds))
        { 
               //接受连接
            int clientfd = accept(sockfd, NULL,NULL);
            if(clientfd < 0)
            {
                perror("accept");
            }            //把客户端套接字保存到cfds数组中
            for(int i=0; i<50; i++)
            {
                if(cfds[i] == 0)//判断放在没有使用的空间中
                {
                     cfds[i] = clientfd;
                     break;
                }
            }
         }        //判断是否是客户端有数据
        for(int i=0; i<50; i++)
        {
            //判断套接字是否存在,并且是否有数据到达
            if(cfds[i] != 0 && FD_ISSET(cfds[i], &readfds))
            { 
                     //接收客户端数据
                char buffer[128]={0};
                int size = recv(cfds[i], buffer, 128, 0);
                if(size<=0)
                {
                    printf("有客户端掉线\n");
                    close(cfds[i]);
                    cfds[i] = 0;
                }
                //把接收到的信息转发给客户端自己
                     size = send(cfds[i],buffer,size,0);

            }
        }
    }
     printf("有客户端连接\n");
    close(sockfd);
 }

以上就是多路复用的代码

标签:addr,多路复用,int,ret,readfds,sockfd,include
From: https://www.cnblogs.com/jiangson1024/p/18247003

相关文章

  • IO的多路复用
    一、select()1.1、处理流程1、创建文件描述符集合fd_set2、添加文件描述符到集合中intFD_ISSET(intfd,fd_set*set);3、通知内核开始监测select 4、内核返回的结果(两个结果,1、是那种类型得文件),做对应得操作(对IO读、写操作)1.2、函数接口(1)select()函数接口 #inc......
  • 【Linux网络编程】I/O 多路复用技术
    【Linux网络编程】I/O多路复用技术什么是I/O多路复用?为什么需要I/O多路复用最简单的socket网络模型,就是单线程模型,一个同时进行监听、处理,然而,单线程模型同时只能服务一个客户端,当线程发生阻塞的时候,其他客户端只能排队等待,甚至连接失败。为了能够同时服务更多的客户端,......
  • [操作系统]IO多路复用
    从阻塞I/O到I/O多路复用阻塞I/O,是指进程发起调用后,会被挂起(阻塞),直到收到数据再返回。如果调用一直不返回,进程就会一直被挂起。因此,当使用阻塞I/O时,需要使用多线程来处理多个文件描述符。多线程切换有一定的开销,因此引入非阻塞I/O。非阻塞I/O不会将进程挂起,调用时会立......
  • 非阻塞套接字与IO多路复用
    非阻塞套接字与IO多路复用非阻塞套接字#【本机环境运行】#01-TCP非堵塞通信.py#使用TCP调试助手作为客户端importsockettcp_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)tcp_socket.bind(("",9000))tcp_socket.listen(128)#设置监听套接字为非......
  • IO多路复用
    概述提高通信的效率(对单个进程来说),在客观的环境下发送和接收是不可能同时接近并发的,可以实现单进程(像同时)发送和接收针对发送的文件描述符是:套接字write,标准输入:stdin/dev/stdin往/dev/stdin读数据针对接收的文件描述符是:套接字,标准输出printf("hello");把he......
  • select多路复用(tcp通信)
    文章目录项目名称项目结构项目名称io_demo1项目结构$tree.├──build├──CMakeLists.txt├──debug.gdb├──include│├──mysocket.h│├──tcp_client.h│└──tcp_server.h├──sources│└──server.cpp└──sr......
  • io多路复用
    io多路复用:文件描述符fd:简单的理解就是磁盘上文件的索引,我们通过客户端程序想要操作磁盘上的文件,是不能直接操作磁盘上的文件的,都是操作的这个文件描述符,然后通过这个文件描述符操作磁盘上的文件。有三种类型:一种是select模型,一种是poll模型,一种是epoll模型。Epoll是Linux底层......
  • 0726_驱动2 io多路复用
    一、工作原理1.当一个app应用程序,如果像读取多个硬件中的数据,监听多个文件描述符,这时就要引入io多路服用机制2.使用select/poll/epoll监听多个文件描述符3.如果所有硬件数据(文件描述)没有准备好,进程进入休眠状态4.如果有一个或者多个硬件数据(文件描述符)准备好。唤醒休眠进......
  • 内核Select、Poll、Epoll多路复用
    Java-NIO的整体结构Java-NIO体系最关键的是Selector选择器,它是整个NIO体系中较为复杂的一块内容,同时它也作为Java-NIO与内核多路复用模型的“中间者”,其中SelectorProvider的作用是什么?主要目的是用于创建选择器,在Java中创建一般是通过如下方式:// 创建Selector选择器Sele......
  • IO多路复用
    IO多路复用select系统调用维护的是一个文件描述符集合,监测这些fd集合。#include<sys/select.h>//头文件运行机制将文件描述符集合复制到内核空间,然后对其进行遍历,查看可读,可写,错误事件,返回就绪事件总数。select函数select函数调用时需要五个参数,包括文件描述符集合总数......