• 探讨【IGE】的源代码【五】。


      这样做,有没有问题????

      

      TGateInfo = record 
        Socket: TCustomWinSocket; 
        sIPaddr: string; 
        sReceiveMsg: string;
        UserList: TList;
        dwKeepAliveTick: LongWord; 
      end;
      pTGateInfo = ^TGateInfo;

      上面正常的信息结构,当然里面包含了一个链表对象,呵呵。

    procedure TFrmMain.GSocketClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    var
      GateInfo: pTGateInfo;
      Config: pTConfig;
    begin
      Config := @g_Config;
      if not ExecTimer.Enabled then begin
        Socket.Close;
        Exit;
      end;
      New(GateInfo);
      GateInfo.Socket := Socket;
      GateInfo.sIPaddr := GetGatePublicAddr(Config, Socket.RemoteAddress);
      GateInfo.sReceiveMsg := '';
      GateInfo.UserList := TList.Create;
      GateInfo.dwKeepAliveTick := GetTickCount();
      EnterCriticalSection(Config.GateCriticalSection);
      try
        Config.GateList.Add(GateInfo);
      finally
        LeaveCriticalSection(Config.GateCriticalSection);
      end;
    end;
    
    procedure TFrmMain.GSocketClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    var
      I: Integer;
      II: Integer;
      GateInfo: pTGateInfo;
      UserInfo: pTUserInfo;
      Config: pTConfig;
    begin
      Config := @g_Config;
      EnterCriticalSection(Config.GateCriticalSection);
      try
        for I := 0 to Config.GateList.Count - 1 do begin
          GateInfo := Config.GateList.Items[I];
          if GateInfo.Socket = Socket then begin
            for II := 0 to GateInfo.UserList.Count - 1 do begin
              UserInfo := GateInfo.UserList.Items[II];
              if Config.boShowDetailMsg then
                MainOutMessage('Close: ' + UserInfo.sUserIPaddr);
              Dispose(UserInfo);
            end;
            GateInfo.UserList.Free;
            Dispose(GateInfo);
            Config.GateList.Delete(I);
            Break;
          end;
        end;
      finally
        LeaveCriticalSection(Config.GateCriticalSection);
      end;
    end;

      上面是服务端和客户端的连接和断开客户端连接的事件。

      很正常,对吧,看出什么问题没有??????

      在高级服务器IOCP完成端口编程里面,我们也会声明两个数据结构,同样会给它们分配内存。但是有些地方不一样。

      其实很多时候,程序的漏洞就是这些貌似没有问题的代码造成的。

      换做以前,我也没有觉得有什么问题在那里。记得我曾经在前面说过,服务器编程跟一般桌面软件编程是有区别的。

      那么最大的区别,就是内存的分配上面。

      做过IOCP编程测试的很容易看出问题在那里。

      对,内存分配上面,这种分配,无论怎么说,都是错误的。

      IOCP编程需要你去管理内存池分配,这个直接关系到服务器长时间运行,性能被显著影响的问题。

      有很多人不了解引擎程序的实际质量情况,当服务器在很短时间内出现性能下滑,都归结为服务器的物理质量问题。

      却不了解这些是软件造成的,大多数时候是这样的。

      每一天,如果玩家大量地上下线,或者给你很温柔地来个机器人大量地上下线,啥都不做,就是上线和下线,那么保证你的机器在很短时间内,卡得跟蜗牛一样。

      难道使用New来分配内存,使用Dispose来释放内存不行吗,行,肯定行,不行,机器不卡B啊,对吧。

      哈哈!!!

      里面还带几个对象呢,一次这样的操作,天知道会出现什么问题。

      其实没有那么神秘,说白了,就是会产生大量的内存碎片的问题而已。

      我没有看到原来原装的源代码是什么样子的,但是我可以告诉你,这样做的人,以前或者现在都缺乏服务器编程相关的经验。

      我们经常谈被攻击的问题,其实很多时候,是你的程序打开了这扇大门而已。

      这些只是整套源代码显露出来的BUG的冰山一角而已。

      后面我们继续去发现它,当然如果把整套源代码的全局变量或者说初始化才使用的变量合并起来,我想,这块“蛋糕”真不小。呵呵。

      也许大家会问,上面的问题怎么解决,一样的,问题知道了,按照你自己的想法去做。

      还是参考IOCP的做法可能好点。  

  • 相关阅读:
    idea设置编译版本
    java.lang.NoClassDefFoundError: Could not initialize class com.github.pagehelper.util.MetaObjectUtil
    Incorrect string value: 'xF0x9Fx92x98xF0x9F...'
    mybatis%_查询
    Executor.query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.sessi
    git 查看当前仓库地址以及设置新的仓库地址
    C#-Linq-使用Linq实现SQL的全连接
    C#-Linq-使用Linq实现SQL的全连接
    JavaScript中匿名函数this指向问题
    Vue设置导航栏为公共模块并在登录页不显示
  • 原文地址:https://www.cnblogs.com/GameDelphi/p/2654816.html
Copyright © 2020-2023  润新知