从零开始实现一个C++高性能服务器框架----Socket模块

这篇具有很好参考价值的文章主要介绍了从零开始实现一个C++高性能服务器框架----Socket模块。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

此项目是根据sylar框架实现,是从零开始重写sylar,也是对sylar丰富与完善
项目地址:https://gitee.com/lzhiqiang1999/server-framework

简介

项目介绍:实现了一个基于协程的服务器框架,支持多线程、多协程协同调度;支持以异步处理的方式提高服务器性能;封装了网络相关的模块,包括socket、http、servlet等,支持快速搭建HTTP服务器或WebSokcet服务器。
详细内容:日志模块,使用宏实现流式输出,支持同步日志与异步日志、自定义日志格式、日志级别、多日志分离等功能。线程模块,封装pthread相关方法,封装常用的锁包括(信号量,读写锁,自旋锁等)。IO协程调度模块,基于ucontext_t实现非对称协程模型,以线程池的方式实现多线程,多协程协同调度,同时依赖epoll实现了事件监听机制。定时器模块,使用最小堆管理定时器,配合IO协程调度模块可以完成基于协程的定时任务调度。hook模块,将同步的系统调用封装成异步操作(accept, recv, send等),配合IO协程调度能够极大的提升服务器性能。Http模块,封装了sokcet常用方法,支持http协议解析,客户端实现连接池发送请求,服务器端实现servlet模式处理客户端请求,支持单Reator多线程,多Reator多线程模式的服务器。文章来源地址https://www.toymoban.com/news/detail-405335.html

Socket模块

1. 主要功能

  • 对Linux下socket相关方法的封装,包括bind、listen、connect、read/write系列等方法。
  • 支持快速创建TCP、UDP对应的Socket。

2. 功能演示

  • 模拟一个请求百度的客户端,并打印出响应
IPAddress::ptr addr = Address::LookupAnyIPAddress("www.baidu.com:80");
// 创建socket
Socket::ptr socket = Socket::CreateTCP(addr);
// 连接
socket->connect(addr);
//发送数据
const char buf[] = "GET / HTTP/1.1\r\n\r\n";
int rt = socket->send(buf, sizeof(buf));
if(rt <= 0) {
    LOG_INFO(g_logger) << "send fail";
    return;
}

//接收数据
std::string buffers;
buffers.resize(4096);
rt = socket->recv(&buffers[0], 4096);
if(rt <= 0) {
    LOG_INFO(g_logger) << "recv fail";
    return;
}

LOG_INFO(g_logger) << buffers;

3. 模块介绍

3.1 Socket

  • 对socket相关方法的封装,包括以下内容
    • 创建各种类型的套接字对象的方法(TCP套接字,UDP套接字,Unix域套接字)
    • 设置套接字选项,比如超时参数
    • bind/connect/listen方法,实现绑定地址、发起连接、发起监听功能
    • accept方法,返回连入的套接字对象
    • 发送、接收数据的方法
    • 获取本地地址、远端地址的方法
    • 获取套接字类型、地址类型、协议类型的方法
    • 取消套接字读、写的方法
    class Socket : public std::enable_shared_from_this<Socket>, Noncopyable
    {
    public:
        typedef std::shared_ptr<Socket> ptr;
        typedef std::weak_ptr<Socket> weak_ptr;

		// 创建TCP Socket(满足地址类型)
        static Socket::ptr CreateTCP(johnsonli::Address::ptr address);
 		// 创建UDP Socket(满足地址类型)
        static Socket::ptr CreateUDP(johnsonli::Address::ptr address);
		// 创建IPv4的TCP Socket
        static Socket::ptr CreateTCPSocket();
		// 创建IPv4的UDP Socket
        static Socket::ptr CreateUDPSocket();
  		// 创建IPv6的TCP Socket
        static Socket::ptr CreateTCPSocket6();
		// 创建IPv6的UDP Socket
        static Socket::ptr CreateUDPSocket6();

        Socket(int family, int type, int protocol = 0);
        virtual ~Socket();

		
        int64_t getSendTimeout();			// 获取发送超时时间(毫秒)
        void setSendTimeout(int64_t v);		// 设置发送超时时间(毫秒)
        int64_t getRecvTimeout();			// 获取接受超时时间(毫秒)
        void setRecvTimeout(int64_t v);		// 设置接受超时时间(毫秒)

    	// 获取sockopt @see getsockopt
        bool getOption(int level, int option, void* result, socklen_t* len);

    	// 获取sockopt模板 @see getsockopt
        template<class T>
        bool getOption(int level, int option, T& result) 
        {
            socklen_t length = sizeof(T);
            return getOption(level, option, &result, &length);
        }

  		// 设置sockopt @see setsockopt
        bool setOption(int level, int option, const void* result, socklen_t len);

   		// 设置sockopt模板 @see setsockopt
        template<class T>
        bool setOption(int level, int option, const T& value) 
        {
            return setOption(level, option, &value, sizeof(T));
        }

        /**
         * @brief 接收connect链接
         * @return 成功返回新连接的socket,失败返回nullptr
         * @pre Socket必须 bind , listen  成功
         */
        virtual Socket::ptr accept();

        /**
         * @brief 绑定地址
         * @param[in] addr 地址
         * @return 是否绑定成功
         */
        virtual bool bind(const Address::ptr addr);

        /**
         * @brief 连接地址
         * @param[in] addr 目标地址
         * @param[in] timeout_ms 超时时间(毫秒)
         */
        virtual bool connect(const Address::ptr addr, uint64_t timeout_ms = -1);

        virtual bool reconnect(uint64_t timeout_ms = -1);

        /**
         * @brief 监听socket
         * @param[in] backlog 未完成连接队列的最大长度
         * @result 返回监听是否成功
         * @pre 必须先 bind 成功
         */
        virtual bool listen(int backlog = SOMAXCONN);

        /**
         * @brief 关闭socket
         */
        virtual bool close();

        /**
         * @brief 发送数据
         * @param[in] buffer 待发送数据的内存
         * @param[in] length 待发送数据的长度
         * @param[in] flags 标志字
         * @return
         *      @retval >0 发送成功对应大小的数据
         *      @retval =0 socket被关闭
         *      @retval <0 socket出错
         */
        virtual int send(const void* buffer, size_t length, int flags = 0);

        /**
         * @brief 发送数据
         * @param[in] buffers 待发送数据的内存(iovec数组)
         * @param[in] length 待发送数据的长度(iovec长度)
         * @param[in] flags 标志字
         * @return
         *      @retval >0 发送成功对应大小的数据
         *      @retval =0 socket被关闭
         *      @retval <0 socket出错
         */
        virtual int send(const iovec* buffers, size_t length, int flags = 0);

        /**
         * @brief 发送数据
         * @param[in] buffer 待发送数据的内存
         * @param[in] length 待发送数据的长度
         * @param[in] to 发送的目标地址
         * @param[in] flags 标志字
         * @return
         *      @retval >0 发送成功对应大小的数据
         *      @retval =0 socket被关闭
         *      @retval <0 socket出错
         */
        virtual int sendTo(const void* buffer, size_t length, const Address::ptr to, int flags = 0);

        /**
         * @brief 发送数据
         * @param[in] buffers 待发送数据的内存(iovec数组)
         * @param[in] length 待发送数据的长度(iovec长度)
         * @param[in] to 发送的目标地址
         * @param[in] flags 标志字
         * @return
         *      @retval >0 发送成功对应大小的数据
         *      @retval =0 socket被关闭
         *      @retval <0 socket出错
         */
        virtual int sendTo(const iovec* buffers, size_t length, const Address::ptr to, int flags = 0);

        /**
         * @brief 接受数据
         * @param[out] buffer 接收数据的内存
         * @param[in] length 接收数据的内存大小
         * @param[in] flags 标志字
         * @return
         *      @retval >0 接收到对应大小的数据
         *      @retval =0 socket被关闭
         *      @retval <0 socket出错
         */
        virtual int recv(void* buffer, size_t length, int flags = 0);

        /**
         * @brief 接受数据
         * @param[out] buffers 接收数据的内存(iovec数组)
         * @param[in] length 接收数据的内存大小(iovec数组长度)
         * @param[in] flags 标志字
         * @return
         *      @retval >0 接收到对应大小的数据
         *      @retval =0 socket被关闭
         *      @retval <0 socket出错
         */
        virtual int recv(iovec* buffers, size_t length, int flags = 0);

        /**
         * @brief 接受数据
         * @param[out] buffer 接收数据的内存
         * @param[in] length 接收数据的内存大小
         * @param[out] from 发送端地址
         * @param[in] flags 标志字
         * @return
         *      @retval >0 接收到对应大小的数据
         *      @retval =0 socket被关闭
         *      @retval <0 socket出错
         */
        virtual int recvFrom(void* buffer, size_t length, Address::ptr from, int flags = 0);

        /**
         * @brief 接受数据
         * @param[out] buffers 接收数据的内存(iovec数组)
         * @param[in] length 接收数据的内存大小(iovec数组长度)
         * @param[out] from 发送端地址
         * @param[in] flags 标志字
         * @return
         *      @retval >0 接收到对应大小的数据
         *      @retval =0 socket被关闭
         *      @retval <0 socket出错
         */
        virtual int recvFrom(iovec* buffers, size_t length, Address::ptr from, int flags = 0);



		// 输出信息到流中
        virtual std::ostream& dump(std::ostream& os) const;
        virtual std::string toString() const;


        bool cancelRead();		// 取消读
        bool cancelWrite();		// 取消写	
        bool cancelAccept();	// 取消accept
        bool cancelAll();		// 取消所有事件

    protected:
        void initSock();				// 设置socket属性
        void newSock();					// 创建socket m_sockfd = socket()
        virtual bool init(int sock);	// 初始化sock,调用initSock

    protected:  
        int m_sockfd;						/// socket句柄        
        int m_family;						/// 协议簇        
        int m_type;							/// 类型       
        int m_protocol;						/// 协议        
        bool m_isConnected;					/// 是否连接        
        Address::ptr m_localAddress;		/// 本地地址   
        Address::ptr m_remoteAddress;   	/// 远端地址
    };
	
	// 流式输出socket
    std::ostream& operator<<(std::ostream& os, const Socket& sock);
}

到了这里,关于从零开始实现一个C++高性能服务器框架----Socket模块的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++高性能服务器网络框架设计与实现

    这篇文章将从两个方面来介绍,一个是服务器中的基础的网络通信部件;另外一个是,如何利用这些基础通信部件整合成一个完整的高效的服务器框架。注意:本文以下内容中的客户端是相对概念,指的是连接到当前讨论的服务程序的终端,所以这里的客户端既可能是我们传

    2024年02月04日
    浏览(37)
  • c++代码实现一个高性能内存池(超详细版本)

    写在前面 本文的内存池代码是改编自Nginx的内存池源码,思路几乎一样。由于Nginx源码的变量命名我不喜欢,又没有注释,看得我很难受。想自己写一版容易理解的代码。这应该是全网独一份的超详细版本了(笑~). 应用场景 写内存池的原理之前,按照惯例先说内存池的应用

    2024年02月06日
    浏览(41)
  • 云原生 | 从零开始,Minio 高性能分布式对象存储快速入手指南

    [ 点击 👉 关注「 全栈工程师修炼指南」公众号 ] 希望各位看友多多支持【关注、点赞、评论、收藏、投币】,助力每一个梦想。 【 WeiyiGeek Blog\\\'s - 花开堪折直须折,莫待无花空折枝  】 作者主页: 【 https://weiyigeek.top 】 博客地址: 【 https://blog.weiyigeek.top 】 作者答疑学习交

    2024年02月08日
    浏览(41)
  • 一、C++项目:仿muduo库实现高性能高并发服务器

    仿mudou库one thread oneloop式并发服务器实现 仿muduo库One Thread One Loop式主从Reactor模型实现高并发服务器: 通过实现的高并发服务器组件,可以简洁快速的完成一个高性能的服务器搭建。并且,通过组件内提供的不同应用层协议支持,也可以快速完成一个高性能应用服务器的搭建

    2024年02月07日
    浏览(35)
  • Nginx - ​一个高性能、灵活可靠的开源Web服务器

    Nginx是什么?   Nginx是一个 高性能的HTTP和反向代理web服务器 ,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。2011年6月1日,nginx 1.0.4发布。   特点是 占有

    2024年02月07日
    浏览(58)
  • [AIGC] Nginx:一个高性能的 Web 服务器和反向代理

    Nginx(engine x)是一个高性能的 Web 服务器和反向代理,它由 Igor Sysoev 于 2002 年开发,并于 2004 年首次发布为开源软件。Nginx 是当今最受欢迎的 Web 服务器之一,它在互联网上被广泛使用,支持 millions 个网站和应用程序。 Nginx 是一个免费、开源、高性能的 Web 服务器和反向代理

    2024年02月20日
    浏览(42)
  • c++高性能264/265实时h5流媒体服务器前后端整体解决方案

    c++高性能264/265实时h5流媒体服务器前后端整体解决方案 下图展示了前端播放效果。 播放1路264视频流,4路265视频流 CPU占用率10%(测试机器上运行着c++服务端和其他工具程序) GPU0占用率17% 1.1 作者测试机器配置 处理器 11th Gen Intel® Core™ i7-11800H @ 2.30GHz 2.30 GHz 机带 RAM 32.0 GB (31.

    2024年02月12日
    浏览(29)
  • cpp-httplib: 轻量级、高性能的C++ HTTP/HTTPS客户端和服务器库

    cpp-httplib 是一个轻量级且高效的 C++ HTTP/HTTPS 客户端和服务器库。它由 Hideaki Sone(yhirose)开发,并在 MIT 许可下发布。该项目的主要目标是提供一种简单易用的方式,在 C++ 应用程序中实现 HTTP 和 HTTPS 功能。 项目仓库地址:https://gitcode.com/yhirose/cpp-httplib cpp-httplib 可用于以下场

    2024年04月09日
    浏览(55)
  • 多路转接高性能IO服务器|select|poll|epoll|模型详细实现

    那么这里博主先安利一下一些干货满满的专栏啦! Linux专栏 https://blog.csdn.net/yu_cblog/category_11786077.html?spm=1001.2014.3001.5482 操作系统专栏 https://blog.csdn.net/yu_cblog/category_12165502.html?spm=1001.2014.3001.5482 手撕数据结构 https://blog.csdn.net/yu_cblog/category_11490888.html?spm=1001.2014.3001.5482 去仓库获

    2024年02月15日
    浏览(47)
  • Linux C++性能优化秘籍:从编译器到代码,探究高性能C++程序的实现之道

    随着大数据、人工智能等技术的飞速发展,程序性能优化的重要性愈发突出。优化性能可以降低资源消耗、提高系统响应速度,从而在有限的硬件资源下,实现更高的吞吐量和处理能力。此外,性能优化也有助于降低能耗、减少散热问题,延长硬件使用寿命。 Linux操作系统具

    2023年04月09日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包