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();
}
相关推荐
人才程序员28 分钟前
【C++拓展】vs2022使用SQlite3
c语言·开发语言·数据库·c++·qt·ui·sqlite
OKkankan1 小时前
实现二叉树_堆
c语言·数据结构·c++·算法
励志的小陈1 小时前
C语言-----扫雷游戏
c语言·开发语言·游戏
Ciderw2 小时前
MySQL为什么使用B+树?B+树和B树的区别
c++·后端·b树·mysql·面试·golang·b+树
yerennuo2 小时前
windows第七章 MFC类CWinApp介绍
c++·windows·mfc
ExRoc2 小时前
蓝桥杯真题 - 填充 - 题解
c++·算法·蓝桥杯
利刃大大3 小时前
【二叉树的深搜】二叉树剪枝
c++·算法·dfs·剪枝
byte轻骑兵4 小时前
【0x0012】HCI_Delete_Stored_Link_Key命令详解
c语言·蓝牙·通信协议·hci
肖田变强不变秃4 小时前
C++实现有限元计算 矩阵装配Assembly类
开发语言·c++·矩阵·有限元·ansys
c++初学者ABC5 小时前
学生管理系统C++版(简单版)详解
c++·结构体·学生管理系统