IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> tcp-server-echo epool -> 正文阅读

[C++知识库]tcp-server-echo epool

直接上代码


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
 
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include<signal.h>

#define LISTENQ 20  //
#define EPOLLEVENTS 512 // 
#define FDSIZE   1024 //

int socket_bind(const char *ip, int port)
{
    int listenfd;
    struct sockaddr_in servaddr;
    listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd == -1)
    {
        perror("socket error:");
        exit(1);
    }
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, ip, &servaddr.sin_addr);
    servaddr.sin_port = htons(port);
 
    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
    {
        perror("bind error: ");
        exit(1);
    }
    return listenfd;
}

int do_accpet(int epollfd, int listenfd)
{
    int clifd,ret;
    struct sockaddr_in cliaddr;
    socklen_t cliaddrlen=sizeof(struct sockaddr_in);
    struct epoll_event ev;

    clifd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddrlen);
    if (clifd == -1)
    {
        perror("server accpet error");
    }
    else
    {
        ev.events = EPOLLIN|EPOLLERR;
        ev.data.fd = clifd;
        ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, clifd, &ev);
        if(ret != 0 )
        {               
            close(clifd); 
        } 
    }
    return 0;
}

int handle_events(int epollfd, struct epoll_event *events, int num, int listenfd)
{
    int i;
    int fd;
    int ret=0;
    uint8_t buf[4096];
    int len=0,nread=0;
    for (i = 0; i < num; i++)
    {
        fd = events[i].data.fd;
        if ((fd == listenfd) && (events[i].events & EPOLLIN))
        {   
            do_accpet(epollfd, listenfd);     
        }          
        else if (events[i].events & EPOLLIN )
        {
            nread = read(fd, buf, 4096); 
            if(nread > 0)
            {
                write(fd, buf,nread);    
            }
            else 
            {
                epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, NULL);
                close(fd);
            }      
        }
        else if (events[i].events & EPOLLOUT )
        {
           
        }
        else if (events[i].events & EPOLLERR)
        {        
            close(events[i].data.fd);
        }
        else
        {
            
        }       
    }
    return ret;
}

int do_epoll(int listenfd)
{
    int epollfd;
    struct epoll_event events[EPOLLEVENTS];
    int ret;
    struct epoll_event ev;
 
    epollfd = epoll_create(FDSIZE);
    if(epollfd<0)
    {
        exit(1);
    }
    ev.events = EPOLLIN;
    ev.data.fd = listenfd;
    epoll_ctl(epollfd, EPOLL_CTL_ADD, listenfd, &ev);
    for (;;)
    {
        ret = epoll_wait(epollfd, events, EPOLLEVENTS, 1000);
        if(ret < 0)
        {
            perror("epoll_wait error");
            exit(1);
        }
        else if (ret>0)
        {                 
            handle_events(epollfd, events, ret, listenfd);                
        }   
        else
        {
                
           
        }     
    }
    close(epollfd);
}


void mydaemon(void)
{
		int i;
		int fd0;
		pid_t pid;
		struct sigaction sa;
		
		umask(0);
		
		pid = fork();
		if(pid < 0){
				perror("fork error!\n");
				exit(1);
		}else if(pid > 0){
				exit(0);
		}
		
		setsid(); //创建一个会话
		
		sa.sa_handler = SIG_IGN;
		sa.sa_flags = 0;
		sigemptyset(&sa.sa_mask);
		
		if(sigaction(SIGCHLD, &sa, NULL) < 0){//注册子进程退出忽略信号
				return ;
		}
		
		if(chdir("/") < 0){//将当前工作目录更改为根目录
				printf("chlid dir error!\n");
				return;
		}
		
		//关闭不需要的文件描述符,或者重定向到/dev/null
		close(0);
		fd0 = open("/dev/null", O_RDWR);
		dup2(fd0, 1);
		dup2(fd0, 2);
}

int main(int argc, char *argv[])
{
    int listenfd,fd;
    char ip[INET6_ADDRSTRLEN]="127.0.0.1";
    int port = 1234;
    int ret,opt;
    char *optstr = "i:p:";
    while((opt = getopt(argc,argv,optstr))!=-1)
    {
        switch(opt)
        {
            case 'i':
                strcpy(ip,optarg);
                break;
            case 'p':
                port = atoi(optarg);
            break;
            case '?':
                printf("run like: ./echo -i 0.0.0.0  -p 1234\n");
                return 0;
            break;
        }
    }

    mydaemon();

    listenfd = socket_bind(ip, port);
    ret = listen(listenfd, LISTENQ);
    if(ret != 0)
    {
      perror("listen error: ");
      exit(1);  
    }
    printf("listen on %s,%d\n",ip,port);
    do_epoll(listenfd);
    return 0;
}




  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-13 22:34:39  更:2022-04-13 22:36:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:57:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码