C/C++轻量级并发TCP服务器框架Zinx-框架开发001: 读取标准输入,回显到标准输出

文章目录


完整代码实现参考-非项目使用

c 复制代码
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/epoll.h>
#include <iostream>
#include <string>
using namespace std;

///stdin_channel类
class stdin_channel{
public:
    bool ReadFd(string &_input)
    {
        cin >> _input;
    }
};

///zinx_kernel类
class zinx_kernel{
    stdin_channel m_channel;
public:
    int iEpollFd;
    bool Add_Channel(stdin_channel &_channel)
    {
        bool bRet = false;

        struct epoll_event stEvent;
        stEvent.events = EPOLLIN;
        stEvent.data.ptr = &_channel;

        if (0 == epoll_ctl(iEpollFd, EPOLL_CTL_ADD, 0, &stEvent))
        {
            m_channel = _channel;
            bRet = true;
        }


        return bRet;
    }
    void Del_Channel(stdin_channel &_channel)
    {
        epoll_ctl(iEpollFd, EPOLL_CTL_DEL, 0, NULL);
    }
    bool run()
    {
        int iEpollRet = -1;

        for (;;)
        {
            struct epoll_event atmpEvent[100];
            iEpollRet = epoll_wait(iEpollFd, atmpEvent, 100, -1);
            if (-1 == iEpollRet)
            {
                if (EINTR == errno)
                {
                    continue;
                }
                else
                {
                    break;

                }

            }
            for (int i = 0; i < iEpollRet; i++)
            {
                stdin_channel *poChannel = static_cast<stdin_channel *>(atmpEvent[i].data.ptr);
                if (0 != (EPOLLIN & atmpEvent[i].events))
                {
                    string input;
                    poChannel->ReadFd(input);
                    cout << input <<endl;
                }

            }
        }


    }
};


///主函数
int main()
{
    zinx_kernel z;
    stdin_channel s;
    z.iEpollFd = epoll_create(1);
    z.Add_Channel(s);
    z.run();

}

项目使用的代码 - 乱-但是思路与上面的相同

Zinxkernel类中引入Channel类

定义一个channel对象,并设置get和set方法。

在stdinChannel类中实现一个ReadFd方法。

创建Kernel类

定义一个channel对象,并设置get和set方法。

但是set方法不适用epoll,应该是添加通道到epoll里,所以使用Addchannel

c 复制代码
#pragma once

#include "stdin_channel.h"
#include "Ichannel.h"

class zinxkernel
{
	stdin_channel *m_channel = nullptr;

	zinxkernel();
	virtual ~zinxkernel();
	static zinxkernel kernel;
public:
	void run();

// 删除set方法
	void AddChannel(Ichannel *_pChannel);
	void DelChannel(Ichannel *_pChannel);
	void ModChannel_AddOut(Ichannel *_pChannel);
	void ModChannel_DelOut(Ichannel *_pChannel);

	stdin_channel *GetChannel()
	{
		return m_channel;
	}
	static zinxkernel &GetInstance()
	{
		return kernel;
	}
};

添加删除修改epoll,才能写run方法

c 复制代码
void zinxkernel::AddChannel(Ichannel * _pChannel)
{
	if (true == _pChannel->init())
	{
		//将参数和文件描述符0关联起来(epoll_ctl)
		struct epoll_event stEvent;
		stEvent.events = EPOLLIN;
		stEvent.data.ptr = _pChannel;

		epoll_ctl(m_epollFd, EPOLL_CTL_ADD, _pChannel->GetFd(), &stEvent);
	}
}

void zinxkernel::DelChannel(Ichannel * _pChannel)
{
	epoll_ctl(m_epollFd, EPOLL_CTL_DEL, _pChannel->GetFd(), NULL);
	_pChannel->fini();
}

void zinxkernel::ModChannel_AddOut(Ichannel * _pChannel)
{
	struct epoll_event stEvent;
	stEvent.events = EPOLLIN | EPOLLOUT;
	stEvent.data.ptr = _pChannel;
	epoll_ctl(m_epollFd, EPOLL_CTL_MOD, _pChannel->GetFd(), &stEvent);
}

void zinxkernel::ModChannel_DelOut(Ichannel * _pChannel)
{
	struct epoll_event stEvent;
	stEvent.events = EPOLLIN;
	stEvent.data.ptr = _pChannel;
	epoll_ctl(m_epollFd, EPOLL_CTL_MOD, _pChannel->GetFd(), &stEvent);
}

创建stdin_Channel类

c 复制代码
std::string stdin_channel::ReadFd()
{
	std::string ret;
	std::cin >> ret;
	return ret;
}

在Kernel类中实现run方法

1 等输入epoll

在哪里创建epoll fd?

在kernel的构造函数中创建。

c 复制代码
zinxkernel::zinxkernel()
{
	int fd = epoll_create(1);
	if (fd >= 0)
	{
		m_epollFd = fd;
	}
}

zinxkernel::~zinxkernel()
{
	if (-1 != m_epollFd)
	{
		close(m_epollFd);
	}
}

等输入

c 复制代码
		struct epoll_event astEvents[200];
		int ready_count = epoll_wait(m_epollFd, astEvents, 200, -1);
		if (0 == ready_count)
		{
			if (EINTR == errno)
			{
				continue;
			}
		}

2 调用输出通道的读取函数

c 复制代码
		//2调用通道的读取函数或写出函数
		for (int i = 0; i < ready_count; i++)
		{
			if (0 != (astEvents[i].events & EPOLLIN))
			{
	// 3 回显到标准输出
				cout<<xxxxx
			}
		}
c 复制代码
int main()
{
	stdin_channel in_channel;

	zinxkernel &kernel = zinxkernel::GetInstance();
	kernel.AddChannel(&in_channel);

	kernel.run();
}
相关推荐
唐诺5 小时前
几种广泛使用的 C++ 编译器
c++·编译器
XH华5 小时前
初识C语言之二维数组(下)
c语言·算法
冷眼看人间恩怨5 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
红龙创客6 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
Lenyiin6 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin
yuanbenshidiaos7 小时前
c++---------数据类型
java·jvm·c++
十年一梦实验室8 小时前
【C++】sophus : sim_details.hpp 实现了矩阵函数 W、其导数,以及其逆 (十七)
开发语言·c++·线性代数·矩阵
taoyong0018 小时前
代码随想录算法训练营第十一天-239.滑动窗口最大值
c++·算法
这是我588 小时前
C++打小怪游戏
c++·其他·游戏·visual studio·小怪·大型·怪物
Uu_05kkq8 小时前
【C语言1】C语言常见概念(总结复习篇)——库函数、ASCII码、转义字符
c语言·数据结构·算法