`
haoningabc
  • 浏览: 1478032 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

epoll简化版本

阅读更多
epoll基于socket
先上socket服务端
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h> 
#include <unistd.h>
#include <netinet/in.h>
#define MAXPENDING 5    /* Max connection requests */
#define BUFFSIZE 32
void Die(char *mess) { perror(mess); exit(1); }
void HandleClient(int sock) {
		char buffer[BUFFSIZE];
		int received = -1;
		if ((received = recv(sock, buffer, BUFFSIZE, 0)) < 0) {
				Die("Failed to receive initial bytes from client");
		}
		while (received > 0) {
				if (send(sock, buffer, received, 0) != received) {
						Die("Failed to send bytes to client");
				}
				if ((received = recv(sock, buffer, BUFFSIZE, 0)) < 0) {
						Die("Failed to receive additional bytes from client");
				}
		}
		close(sock);
}
int main(int argc, char *argv[]) {
        int serversock, clientsock;
        struct sockaddr_in echoserver, echoclient;
        if (argc != 2) {
          fprintf(stderr, "USAGE: echoserver <port>\n");
          exit(1);
        }
        if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
          Die("Failed to create socket");
        }
        memset(&echoserver, 0, sizeof(echoserver));       /* Clear struct */
        echoserver.sin_family = AF_INET;                  /* Internet/IP */
        echoserver.sin_addr.s_addr = htonl(INADDR_ANY);   /* Incoming addr */
        echoserver.sin_port = htons(atoi(argv[1]));       /* server port */
		if (bind(serversock, (struct sockaddr *) &echoserver,sizeof(echoserver)) < 0) {		 /* Bind the server socket */
				Die("Failed to bind the server socket");
		}
		if (listen(serversock, MAXPENDING) < 0) {		/* Listen on the server socket */
				Die("Failed to listen on server socket");
		}
		while (1) {
				unsigned int clientlen = sizeof(echoclient);
				if ((clientsock =accept(serversock, (struct sockaddr *) &echoclient,&clientlen)) < 0) {/* Wait for client connection */
						Die("Failed to accept client connection");
				}
				fprintf(stdout, "Client connected: %s\n",inet_ntoa(echoclient.sin_addr));
				HandleClient(clientsock);
		}
}


client
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#define BUFFSIZE 32
void Die(char *mess) {perror(mess);exit(1);}
int main(int argc, char *argv[]) {
		int sock;
		struct sockaddr_in echoserver;
		char buffer[BUFFSIZE];
		unsigned int echolen;
		int received = 0;
		if (argc != 4) {
				fprintf(stderr, "USAGE: TCPecho <server_ip> <word> <port>\n");
				exit(1);
		}
		if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
				Die("Failed to create socket");
		}
    memset(&echoserver, 0, sizeof(echoserver));       /* Clear struct */
    echoserver.sin_family = AF_INET;                  /* Internet/IP */
    echoserver.sin_addr.s_addr = inet_addr(argv[1]);  /* IP address */
    echoserver.sin_port = htons(atoi(argv[3]));       /* server port */
    if (connect(sock,(struct sockaddr *) &echoserver,sizeof(echoserver)) < 0) {
      Die("Failed to connect with server");
    }
    echolen = strlen(argv[2]);
    if (send(sock, argv[2], echolen, 0) != echolen) {
      Die("Mismatch in number of sent bytes");
    }
    fprintf(stdout, "Received: ");/* Receive the word back from the server */
    while (received < echolen) {
      int bytes = 0;
      if ((bytes = recv(sock, buffer, BUFFSIZE-1, 0)) < 1) {
        Die("Failed to receive bytes from server");
      }
      received += bytes;
      buffer[bytes] = '\0'; /* Assure null terminated string */
      fprintf(stdout, buffer);
    }
    fprintf(stdout, "\n");
    close(sock);
    exit(0);    
}            


epoll在这个基础上改造一下
epolltest.c
#include <iostream>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
using namespace std;
#define MAXLINE 5
#define OPEN_MAX 100
#define LISTENQ 20
#define SERV_PORT 5000
#define INFTIM 1000
void setnonblocking(int sock){
    int opts;
    opts=fcntl(sock,F_GETFL);//apue第三章讲了
    if(opts<0){
        perror("fcntl(sock,GETFL)");
        exit(1);
    }
    opts = opts|O_NONBLOCK;
    if(fcntl(sock,F_SETFL,opts)<0){
        perror("fcntl(sock,SETFL,opts)");
        exit(1);
    }   
}
int main(){
    int i, maxi, listenfd, connfd, sockfd,epfd,nfds;
    ssize_t n;
    char line[MAXLINE];
    socklen_t clilen;
    struct epoll_event ev,events[20];//声明epoll_event结构体的变量,ev用于注册事件,数组用于回传要处理的事件
    epfd=epoll_create(256);//生成用于处理accept的epoll专用的文件描述符
    struct sockaddr_in clientaddr,serveraddr;
    listenfd = socket(AF_INET, SOCK_STREAM, 0);  
    //setnonblocking(listenfd);//把socket设置为非阻塞方式  
    ev.data.fd=listenfd;//设置与要处理的事件相关的文件描述符
    ev.events=EPOLLIN|EPOLLET;//ev.events=EPOLLIN;   
    epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);//注册epoll事件,EPOLL_CTL_ADD
    bzero(&serveraddr, sizeof(serveraddr));//memset(&echoserver, 0, sizeof(echoserver));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);//char *local_addr="192.168.229.129";inet_aton(local_addr,&(serveraddr.sin_addr));
    serveraddr.sin_port=htons(SERV_PORT);
    bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr));
    listen(listenfd, LISTENQ);
    maxi = 0;
    while(1){//for ( ; ; ) {    
        nfds=epoll_wait(epfd,events,20,500);//等待epoll事件的发生    
        for(i=0;i<nfds;++i){
            if(events[i].data.fd==listenfd){
                connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen);
                if(connfd<0){
                    perror("connfd<0");
                    exit(1);
                }
                //setnonblocking(connfd);
                char *str = inet_ntoa(clientaddr.sin_addr);
                cout << "accapt a connection from " << str << endl; 
                ev.data.fd=connfd;//设置用于读操作的文件描述符
                ev.events=EPOLLIN|EPOLLET; //ev.events=EPOLLIN;//设置用于注测的读操作事件
                epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);//注册ev
            }else if(events[i].events&EPOLLIN){
                cout << "EPOLLIN" << endl;
                if ( (sockfd = events[i].data.fd) < 0) continue;
                if ((n = read(sockfd, line, MAXLINE)) < 0) {
                    if (errno == ECONNRESET) {
                        close(sockfd);
                        events[i].data.fd = -1;
                    } else{
                        std::cout<<"readline error"<<std::endl;
                    }
                } else if (n == 0) {
                    close(sockfd);
                    events[i].data.fd = -1;
                }
                line[n] = '\0';
                cout << "read " << line << endl;
                ev.data.fd=sockfd;//描述符   
                ev.events=EPOLLOUT|EPOLLET;//设置用于注测的写操作事件 //修改sockfd上要处理的事件为EPOLLOUT //epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
            }else if(events[i].events&EPOLLOUT){   
                sockfd = events[i].data.fd;
                write(sockfd, line, n);
                ev.data.fd=sockfd;//设置用于读操作的文件描述符
                ev.events=EPOLLIN|EPOLLET;//设置用于注测的读操作事件
                epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);//修改sockfd上要处理的事件为EPOLIN
            }
        }
    }
    return 0;
}
分享到:
评论

相关推荐

    linux epoll的封装类

    这个“linux epoll的封装类”是为了简化epoll接口的使用,使得初学者能够更轻松地理解和应用epoll机制。 epoll的工作原理主要是通过`epoll_create`、`epoll_ctl`和`epoll_wait`这三个核心函数来实现。`epoll_create...

    linux epoll 的实现

    另外,epoll支持“one-shot”模式,只需处理一次事件后,文件描述符自动从epoll实例中移除,简化了编程逻辑。 总之,`epoll`是Linux提供的一种强大且高效的I/O多路复用机制,尤其适合处理大规模并发连接。通过`...

    epoll_sever linux下用epoll编写的服务器

    在实际应用中,`epoll Sever`还可以结合其他技术,如`SIGEV_THREAD`信号处理程序,用于异步地处理`epoll_wait`返回的事件,或者使用`libevent`、`libev`等库来简化`epoll`的使用。总之,`epoll`为Linux提供了强大的I...

    linux_epoll

    封装的目标是简化`epoll`的使用,使代码更易理解和维护。 5. **epoll_server**实现 - 初始化:创建`epoll`实例,绑定并监听服务器套接字,然后将服务器套接字添加到`epoll`中。 - 接受连接:在`epoll_wait`返回后...

    epoll 服务程序和测试程序

    "只有主干流程,没有对细节进行处理"意味着代码可能简化了某些功能,专注于核心的事件处理机制,这在快速原型开发或初步测试时常见。"压缩文件中包含一个测试程序"意味着除了服务器端代码,还有用于验证和测试服务器...

    epoll_socket.zip

    2. **socket服务端封装**:对socket的创建、绑定、监听、接受连接等步骤进行了封装,简化了服务器端的网络编程。 3. **事件处理**:可能包括了对EPOLLIN(可读)、EPOLLOUT(可写)和EPOLLHUP(连接断开)等事件的...

    Linux操作系统下epoll反应堆代码

    - epoll是Event Poll的缩写,主要在Linux 2.5版本之后引入,提供了基于事件驱动的I/O模型。 - 它支持水平触发(LT)和边缘触发(ET)两种模式。水平触发意味着只要文件描述符上有数据可读或可写,就会通知;边缘...

    linux 网络库 C++ epoll

    该网络库的核心是epoll模型的封装,通过C++的面向对象特性,将epoll的创建、监听、事件注册和轮询等操作进行了抽象,简化了开发者对底层细节的处理。这样,开发者可以更专注于业务逻辑,而无需关心底层的I/O操作。 ...

    C++ epoll方式 client与server stocket连接通信例子.zip

    为了简化编程,通常我们会将上述的socket和epoll操作封装成类,如`Socket`和`Epoll`,提供更高级别的接口供用户使用。 8. **学习与实践**: 这个"C++ epoll client与server stocket连接通信例子"是一个很好的学习...

    linux_C++ tcpEpoll 的简单实现

    下面是一个简化的步骤: 1. **创建服务器套接字**:使用`socket`函数创建一个IPv4的TCP套接字。 2. **绑定地址**:使用`bind`函数将套接字与特定的IP地址和端口号关联。 3. **监听连接**:调用`listen`函数设置...

    优于select的epoll1

    这样,当epoll_wait返回时,开发者可以直接获取到与事件相关的数据,简化了处理流程。 以下是一个简单的epoll实现的echo服务器示例: ```c #include &lt;sys/epoll.h&gt; #include #include #include #include #...

    C语言并行爬虫(epoll).zip

    常用库如libcurl可以帮助我们简化网络通信过程,通过API接口实现网络请求。 再者,本项目采用了epoll作为并发I/O模型。epoll是Linux内核提供的一个I/O多路复用技术,它解决了传统select/poll的性能瓶颈,特别是当...

    linux下使用epoll基于socket套接字的通信库。.zip

    2. **库文件**:可能是一个预编译好的动态库或静态库,提供了一些封装好的epoll接口,简化了epoll的使用,便于开发。 3. **测试脚本**:用于验证库功能的正确性和性能的测试用例,可能包括客户端和服务器端的交互...

    epoll_api:用于epoll的Rust API

    - **异步编程支持**:Rust 的 async/await 语法可以与 `epoll_api` 结合,简化异步操作的编写,让开发者能够以同步代码的风格编写异步逻辑。 - **事件驱动**:`epoll_api` 可能包含了处理事件触发后执行回调函数的...

    linux epoll 解释

    这种方式降低了编程复杂度,适合于那些希望简化编程逻辑而不牺牲太多性能的应用场景。 2. **边缘触发(ET)模式** - 这是一种高性能的工作模式,仅支持非阻塞 socket。在此模式下,当文件描述符的状态由未就绪变为...

    pi-pi-net 是一个在linux环境下封装epoll的网络库.zip

    **pi-pi-net 网络库:...总之,`pi-pi-net` 是一个强大的 Linux 网络库,通过封装 `epoll`,简化了高性能网络应用的开发。它不仅提供了基础的网络操作,还支持构建复杂的网络框架,是 Linux 环境下开发者的得力助手。

    ehttp:基于epoll的简单http服务器

    综上所述,`ehttp`项目旨在创建一个简单的、高效的HTTP服务器,利用了C++的面向对象特性以及Linux系统的`epoll`机制,可应用于微服务架构,处理JSON格式的数据,并且可能依赖于一个名为`HTTPC++`的库来简化HTTP协议...

    C语言并行爬虫(epoll)读写操作代码

    c语言文件读写操作代码。在C语言中实现一个基于epoll的并行爬虫是一个相对复杂的任务,因为它涉及到网络编程、异步I/O、HTML解析等多个...下面我将给出一个简化的示例,说明如何使用epoll来并发地处理多个网络连接。

Global site tag (gtag.js) - Google Analytics