• QQ 324186207群 enet交流技术,主要是为了研究tcp内部执行机制。欢迎大家增加探讨。小弟水平有限,翻译难免有误。



    http://enet.bespin.org

  • 解析enet 双向链表(无placement new) enet本身就已经局限了4095 在线人数   假设有10000人同一时候在线。enet使用list来维护每次收发,不断的销毁,释放内存,性能实在太低。

    enent写的根本不严谨,无论什么结构都存储双向链表,收一个包,我也须要去遍历,究竟获取某peer。

  • enet_host_service  每次事件抛出机制,实在太粗糙。说明enet
     很多其它偏向就是一个学习项目,假设大量数据传输,高并发,高负载,无法满足需求
  • 顺便提下。为何server好多地方不使用stl
  • 问题一:不能确定STL怎样管理内存。如果就依照STL默认的方法来管理内容。则server在长时间的分配和释放内存后,easy导致内存碎片。对server的稳定有影响。然而,如果没有阅读过STL的源代码。谁又能确切地得知STL是怎样管理内存的呢?尽管可以在STL中使用自己的分配器,又可以确认STL的某些部分不会在分配器之外进行内存分配呢?

    当然,内存管理问题不是STL带来的问题,不论什么server程序本身都要考虑这个问题。原因在极少有人去阅读STL的源代码。去了解STL的内部实现机理。由于不了解,所以怀疑。由于怀疑,所以不轻易使用。

    问题二:不能确定STL在海量数据下的表现。

    server一般都是海量的内存,为了提高性能大量数据保存在内存中。

    在很大的规模的数据下。STL一定可以满足稳定性和效率的需求吗?

    问题三:不能确定STL在多线程环境下的表现。

    以上的内存和规模的问题能够通过加深对STL的了解和測试来解决,可是多线程下的并发问题就不是那么easy攻克了。

    STL不是线程安全的。在多线程环境下。对STL容器的操作都要加锁来确保正确。然后。部分高性能的场合,须要对“读-读”条件下并发进行优化,以及某些锁无关的特殊条件能够不加锁,甚至是採用流行的RCU机制…………在这个倡导多核和并发的时代,STL显得有些落后了。

  • 传统的双向链表 普通情况我们套上 T *data
  • /*双链表结构*/
  • template<class T>
  • typedef struct node
  • {
  • T  *data;
  • struct node *prior;
  • struct node *next;
  • }DNode;
  • 下面enet双向链表结构,发现结构体内无T *data ,奇怪吧?那么我们数据存储到哪里?
  • #list.h
  • typedef struct _ENetListNode
  • {
  • struct _ENetListNode * next;
  • struct _ENetListNode * previous;
  • } ENetListNode;
  • typedef ENetListNode *
    ENetListIterator;
  • typedef struct _ENetList
  • {
  • ENetListNode sentinel;  //标记当前处于某个节点位置
  • } ENetList;
  • extern void enet_list_clear( ENetList * );
  • extern ENetListIterator enet_list_insert( ENetListIterator , void * );
  • extern void * enet_list_remove( ENetListIterator );
  • extern ENetListIterator enet_list_move( ENetListIterator, void *, void * );
  • extern size_t enet_list_size( ENetList * );
  • #define enet_list_begin(list) ((list) -> sentinel.next)
  • #define enet_list_end(list) (& (list) -> sentinel)
  • #define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list))
  • #define enet_list_next(iterator) ((iterator) -> next)
  • #define enet_list_previous(iterator) ((iterator) -> previous)
  • #define enet_list_front(list) ((void *) (list) -> sentinel.next)
  • #define enet_list_back(list) ((void *) (list) -> sentinel.previous)
  • #main.cpp
  • #define ENET_CALLBACK __cdecl
  • typedef struct _ENetCallbacks
  • {
  • void * ( ENET_CALLBACK * malloc ) ( size_t size );
  • void ( ENET_CALLBACK * free ) ( void * memory );
  • void ( ENET_CALLBACK * no_memory ) ( void );
  • } ENetCallbacks;
  • static ENetCallbacks callbacks = { malloc, free, abort };
  • void * enet_malloc( size_t size )
  • {
  • void * memory = callbacks.malloc( size );
  • if( memory == NULL )
  • callbacks.no_memory();
  • return memory;
  • }
  • void  enet_free( void * memory )
  • {
  • callbacks.free( memory );
  • }
  • struct ENetOutgoingCommand
  • {
  • ENetListNode list;
  • int a;
  • };
  • int main()
  • ENetOutgoingCommand *enet_outgoing;
  • ENetList enet_test;
  • enet_list_clear(&enet_test); //重置双向链表,将头指针和尾指针指向第一个空节点
  • enet_outgoing = (ENetOutgoingCommand *)enet_malloc( sizeof( ENetOutgoingCommand ) );
  • enet_outgoint->a = 100;
  • enet_list_insert( enet_list_end( &enet_test ), enet_outgoing ); //malloc
    数据插入到双向链表的尾部
  • ENetListIterator currentCommand;
  • currentCommand = enet_list_begin(&enet_test ); //这里取出双向链表头节点
  • while( currentCommand != enet_list_end( &enet_test ) ) //遍历链表
  • {
  • ENetOutgoingCommand * t1 = (ENetOutgoingCommand *)currentCommand;  //通过强转来获取数据
  • cout << t1->a << endl;
  • currentCommand = enet_list_next( currentCommand ); //获取下个节点
  • enet_list_remove( &t1->list ); //删除当前节点
  • enet_free( t1 );//删除内存,避免内存泄漏
  • while( Exit )
  • {
  • 開始server循环机制,这个循环设计非常的糟糕,每次一但server触发事件,会调用不同类型事件。

  • 解决的方法,每个while 我用队列收一把全部数据。然后在逐个遍历,这样添加了非常小延迟,可是提高了吞吐量。
  • 每次收到数据后。又从新  enet_protocol_send_outgoing_commands 開始检查第一个玩家,应该做个全局变量,存储当前遍历
          位置
  • ENetEvent event;
  • if( enet_host_service( server, &event, 1 ) )
  • {
  • switch( event.type )
  • {
  • case ENET_EVENT_TYPE_CONNECT:
  • {
  • Conneted( event.peer->connectID, event.peer->address.host, event.peer->address.port );
  • peersConn.Insert( event.peer->connectID, event.peer );
  • break;
  • }
  • case ENET_EVENT_TYPE_RECEIVE:
  • {
  • //bIdle = false;
  • //Recived( event.peer->connectID, event.packet->data, event.packet->dataLength );
  • break;
  • }
  • case ENET_EVENT_TYPE_DISCONNECT:
  • {
  • cout << "close client_fd" << endl;
  • //Disconneted( event.connectID );
  • break;
  • }
  • case ENET_EVENT_TYPE_PING:
  • {
  • cout << "enter reconnect:" << time( 0 ) << endl;
  • //ReConnection(event.peer->connectID);
  • break;
  • }
  • }
  • }
  • }
  • /** Waits for events on the host specified and shuttles packets between
  • the host and its peers.
  • @param host    host to service
  • @param event   an event structure where event details will be placed if one occurs
  • if event == NULL then no events will be delivered
  • 通向码农的道路(enet开源翻译计划 二)的更多相关文章

    1. 通向码农的道路(enet开源翻译计划 一)

      QQ 324186207群 enet交流技术.主要是为了研究tcp内部执行机制,欢迎大家增加探讨.小弟水平有限.翻译难免有误. . Features: ENet evolved specificall ...

    2. android码农神器 偷懒工具 android懒人框架 LoonAndroid 3 讲解

      LoonAndroid 3.0 Loonandroid是一个注解框架,不涉及任何UI效果,目的是一个功能一个方法,以方法为最小颗粒度对功能进行拆解.把功能傻瓜化,简单化,去掉重复性的代码,隐藏复杂的实 ...

    3. Android码农如何一个星期转为iOS码农(不忽悠)

      WeTest 导读 作为一个android客户端开发,如果你不懂点ios开发,怎么好意思说自己是客户端开发呢,本文讲解如何让android开发码农在一个星期上手IOS开发 --<记录自己IOS开 ...

    4. 拥抱Mac之码农篇

      拥抱Mac之码农篇 使用Mac大概两年时间.之前用着公司配的一台27寸的iMac.无奈机械硬盘严重拖慢速度,影响工作心情.于是入手Macbook Retina 13.这两年的开发工作所有在Mac上完毕 ...

    5. 【整理】待毕业.Net码农就业求职储备

      声明:本文题目来源于互联网,仅供即将从学校毕业的.Net码农(当然,我本人也是菜逼一个)学习之用.当然,学习了这些题目不一定会拿到offer,但是针对就业求职做些针对性的准备也是不错的.此外,除了技术 ...

    6. <开心一笑> 码农 黑客和2B程序员之间的区别

      笔记本电脑 码农: 黑客: 2B程序员: 求2的32次方: 码农: System.out.println(Math.pow(2, 32)); 黑客: System.out.println(1L< ...

    7. [2013 eoe移动开发者大会]靳岩:从码农到极客的升级之路

      (国内知名Android开发论坛 eoe开发者社区推荐:http://www.eoeandroid.com/) 前天,2013 eoe 移动开发者大会在国家会议中心召开,eoe 开发者社区创始人靳岩在 ...

    8. 《码农周刊》干货精选(Python 篇)

      <码农周刊>已经累计发送了 38 期,我们将干货内容进行了精选.此为 Python 篇. <码农周刊>往期回顾:http://weekly.manong.io/issues/ ...

    9. 一名Java架构师分享自己的从业心得,从码农到架构师我用了八年

      工作了挺久,发现有个挺有意思的现象,从程序员.高级程序员,到现在挂着架构师.专家之类的头衔,伴随着技术和能力的提高,想不明白的事情反而越来越多了. 这些疑问有些来自于跟小伙伴的交流,有些是我的自问自答 ...

    随机推荐

    1. iOS 怎样更新APP

      app更新的流程思想 得到当前版本currentVersion,将currentVersion与近期的版本latestVersion进行比較,若当前currentVersion较小.进行更新操作. 获 ...

    2. STL - 容器 - Array

      Array是C++ 11给STL新增加的容器 ArrayTest.cpp #include <array> #include <algorithm> #include < ...

    3. MVC4.0网站发布

      一.VS2010下MVC4.0项目的发布 首先,生成网站发布文件. 第一步,"右击"要发布的MVC4.0项目,选择"发布(B)..."选项,如图: 第二步,在& ...

    4. HDU 4902 Nice boat 成段线段树

      操作1 的时候标记deng[rt]表示以下一段数都是与当前节点的值同样 下次操作2时直接对有deng标记的节点gcd更新 (可能还能够更简单) #include <stdio.h> #in ...

    5. HDUOj Ignatius and the Princess III 题目1002

       母函数  组合数学 #include<stdio.h> int c1[125]; int c2[125]; int main() { int n,i,j,k; while(scanf ...

    6. &quot;高可用方案工具包&quot; high availability toolkit 1.2 公布了。version 1.2 新增了 负载均衡 load balance 的技术实现

      "高可用方案工具包"  high availability toolkit 1.2 公布了. version 1.2 新增了 负载均衡 load balance 的技术实现. 项目 ...

    7. lftp mirror 上传目录

      1. lftp的确很强大, 要学习一下.       sudo yum install lftp       (测试了一下,ftp软件才92K,lftp有2.3M) 2. lftp mirror 能上 ...

    8. [Python]网络爬虫(七):Python中的正则表达式教程

      转自:http://blog.csdn.net/pleasecallmewhy/article/details/8929576#t4 接下来准备用糗百做一个爬虫的小例子. 但是在这之前,先详细的整理一 ...

    9. Python之os.walk()

      #http://www.cnblogs.com/bluescorpio/archive/2009/10/21/1587493.html os.walk() 返回结果:可以得到一个(dirpath, d ...

    10. 判断URL是否支持断点续传?

      #python #xiaodeng #判断URL是否支持断点续传? import urllib2 req = urllib2.Request('http://ftp.ubuntu.com/') req ...