35 | 答疑:编写高性能网络编程框架时,都需要注意哪些问题?
该思维导图由 AI 生成,仅供参考
为什么在发送数据时,会先尝试通过 socket 直接发送,再由框架接管呢?
- 深入了解
- 翻译
- 解释
- 总结
本文主要讨论了在编写高性能网络编程框架时需要注意的问题。作者通过Q&A的形式回答了读者关于数据发送时先尝试通过socket直接发送,再由框架接管的疑问。文章指出,这种处理方式旨在提高发送效率,通过直接发送数据到套接字缓冲区,避免了数据拷贝的过程,在大部分场景下已经满足数据发送的需要。而当网络条件变差或待发送数据较大时,框架会将数据缓冲到发送缓冲区中,并由事件分发机制负责发送。这种设计能够在高效处理条件下直接发送数据,同时在处理效率变慢或待发送数据较大时进行缓冲,保证了整体的发送效率和稳定性。 文章还详细介绍了回调函数的设计,以及tcp_connection对象的设计和其与channel对象的联系和区别。此外,还讨论了主线程等待子线程完成的同步锁问题以及channel_map的设计,特别是内存方面的设计。总的来说,本文通过具体的代码分析和解释,深入浅出地阐述了高性能网络编程框架的设计理念和实现细节,为读者提供了有益的技术指导。
《网络编程实战》,新⼈⾸单¥59
全部留言(32)
- 最新
- 精选
- 酸葡萄为什么在发送数据时,会先尝试通过 socket 直接发送,再由框架接管呢? 老师你好,这个问题中,发送缓冲区有数据说明发送效率低(数据多,网络差等原因导致),没有注册WRITE事件是什么意思呢?(感觉这时一个基础问题[小尴尬])
作者回复: 有两种发送数据的方式,第一种是通过注册WRITE事件,等待reactor来驱动我们把数据发送出去;第二种是不需要reactor驱动,直接往套接字上发送。这里的解释是说,在大部分情况下,为了效率,直接往套接字上发送,当一次解决不了时,再通过reactor来驱动数据发送。
2019-11-3010 - Geek_63bb29谢谢盛老师,链接是关于实战代码的流程图 https://app.yinxiang.com/fx/7e601cad-6501-4fe7-8e4e-f0fbd9d02c4b
作者回复: ������
2020-07-3026 - 范闲这是我改造的c++版本,目前还在调试中 https://gitee.com/willam-dialogue/net_reactor 调试过程中遇到了几个问题: 1.在telnet以后, 客户端第一次发送消息,可以正常收到消息. 客户端第二次发送消息,会导致server coredump. 目前初步定位到问题是发生在TcpConnection.h中的sendData函数,更具体的原因没有找到 2.如果将回调函数注册为如下方式: TcpConnection 公有云继承了enabled_shared_from_this typedef std::shared_ptr<TcpConnection> TcpConnectionPtr; typedef std::function<void (const TcpConnectionPtr &)> ConnCompleteCallBack; typedef std::function<void (const TcpConnectionPtr &)> ConnCloseCallBack; typedef std::function<void (const TcpConnectionPtr &)> WriteCompleteCallBack; typedef std::function<void (Buffer*, const TcpConnectionPtr &)> MessageCallBack; 在TcpConnection调用ConnCompleteCallBack就没有问题. 但是在channel中绑定了TcpConnection.h 中的handleRead和handleWrite的回调,在调试过程中会报weak_ptr的相关错误.实际定位发现在handleRead里面调用了MessageCallBack的回调,MessageCallBack的入参是shared_from_this(),weak_ptr的错误由这个产生的,目前还在看是否因为使用方法的原因引起的. 希望同学们能够一起帮忙看看 这些问题, 我还没找到好的方法.邮箱hy572801400@163.com
作者回复: 给你顶一下,大家一起帮忙看(PS:我最近有点忙,闲下来也来帮你一起看)
2020-03-2725 - 王小白白白首先非常感谢老师的课程,系统的学习了网络编程相关知识,受益匪浅。 这里是我改写的c++ epoll服务器版本,https://github.com/wangxiaobai-dd/BowServer 主要改动有: 1,使用c++语法,智能指针,variant,std::mutex,std::thread等,代码结构有些改变 2,消除一些内存泄漏,(buffer相关待做) 3,加入一个事件队列channel_queue,这样event_dispatch可以改为非阻塞,取消唤醒机制 4, 有新连接时选择任务数最少的连接 5,epoll del ,update 接口有所修改 会持续完善优化项目,一起学习进步~ 有帮助的话点个星星嘻嘻
作者回复: 赞,已点。
2020-08-014 - CofCai我最开始是直接一头代码的细节里面去,没先从宏观上有个把握,然后读的很痛苦。于是自己就借助一些工具,比如思维导图画一下函数调用关系、各种结构体对象的关系,总算有一点头绪了。贴上我的学习笔记(笔记是边读源码边写的,有的理解后来觉得不对,但可能没来得及修改,希望各位伙伴带着思考): 各种结构体对象关系:https://www.processon.com/view/link/5ead14555653bb6efc7cbe59
作者回复: 强大,请问我可以引用么?
2022-01-2232 - 日就月将老师 您写的代码好像没有加内存释放处理
作者回复: 有可能遗漏的,能帮忙在githut提MR么?
2021-10-202 - 范闲https://gitee.com/willam-dialogue/net_reactor 这是目前我改造的cpp版本,正在调试中。 调试过程中遇到一些问题 1.telnet连接以后,第一次发送消息正常。但是第二次发送消息就会coredump, 初步定位到问题出在TcpConnection.h 中的sendData函数中,具体原因还在排查 2.如果将回调函数改成 typedef std::shared_ptr<TcpConnection> TcpConnectionPtr; typedef std::function<void (const TcpConnectionPtr &)> ConnCompleteCallBack; typedef std::function<void (const TcpConnectionPtr &)> ConnCloseCallBack; typedef std::function<void (const TcpConnectionPtr &)> WriteCompleteCallBack; typedef std::function<void (Buffer*, const TcpConnectionPtr &)> MessageCallBack;
作者回复: C++的模板太强大了,不过也很复杂,加油~
2020-03-272 - yusuf// add event read for the new connection struct channel *channel1 = channel_new(connected_fd, EVENT_READ, handle_read, handle_write, tcpConnection); 请问这里第4个参数设置了handle_write函数,为什么第2个参数没有设置EVENT_WRITE呢? 原本以为这个地方是漏掉了EVENT_WRITE,可添加上EVENT_WRITE后,发现tcp服务器收到数据后会一直打印,而http服务器响应一次请求后会崩溃。这又是为什么呢?
作者回复: 这里是向reactor注册了数据可读的事件,注意这个时候缓冲区是没有写入的需求的,如果注册了可写事件,相当于这个事件是肯定会发生的(因为套接字写缓冲区都是空的,可以往里写),所以这个时候你会看到一直会打印。 也就是说,只有在真正有数据需要发送的时候,才需要注册EVENT_WRITE,让reator驱动把需要发送的数据发送完。
2019-11-262 - 范龙dragon哪位大神回答下,框架中哪里有释放tcp_connection和channel资源的地方,从代码中看到这两个对象都是malloc出来的,但没找到在哪里free的,求指教!
作者回复: 我的锅,应该在tcp_connection_shutdown函数里面释放channel和tcp_connection两个对象。抽空改下。
2020-07-1531 - bbbi老师,好像您封装的这个框架跟netty神似
作者回复: 嗯,应该说基于事件分发机制的框架,大致的思想都是相同的,不信你可以再去看看ACE, libevent或者其他的库。
2020-03-2621