亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? iocpsvr.pas

?? iocp小程序
?? PAS
?? 第 1 頁 / 共 2 頁
字號:
{*******************************************************}
{                                                       }
{       高性能服務器,這個是一個演示DEMO                }
{                                                       }
{       聯系郵箱:fansheng_hx@163.com                   }
{                                                       }
{*******************************************************}

unit IOCPSvr;

interface

uses
 Windows, Messages, WinSock2, Classes, SysUtils, SyncObjs;

const
  {* 每一次發送和接收的數據緩沖池大小 *}
  MAX_BUFSIZE = 4096;
  {* 關閉客戶端通知消息 *}
  WM_CLIENTSOCKET = WM_USER + $2000;

type
  {* Windows Socket 消息 *}
  TCMSocketMessage = packed record
    Msg: Cardinal;
    Socket: TSocket;
    SelectEvent: Word;
    SelectError: Word;
    Result: Longint;
  end;

  {* IOCP服務器運行軌跡 *}
  TSocketEvent = (seInitIOPort, seUninitIOPort, seInitThread, seUninitThread,
    seInitSocket, seUninitSocket, seConnect, seDisconnect, seListen, seAccept, seWrite, seRead);
const
  CSSocketEvent: array[TSocketEvent] of string = ('InitIOPort', 'UninitIOPort', 'InitThread', 'UninitThread',
    'InitSocket', 'UninitSocket', 'Connect', 'Disconnect', 'Listen', 'Accept', 'Write', 'Read');
type
  {* 產生錯誤類型 *}
  TErrorEvent = (eeGeneral, eeSend, eeReceive, eeConnect, eeDisconnect, eeAccept);

  {* 完成端口傳遞的結構體 *}
  TIOCPStruct = packed record
    Overlapped: OVERLAPPED;
    wsaBuffer: TWSABUF;
    Event: TSocketEvent; //讀或寫
    Buffer: array [0..MAX_BUFSIZE - 1] of Char;
    Assigned: Boolean;  //表示已經分配給某個客戶端
    Active: Boolean;    //客服端內部使用,表示是否正在使用
  end;
  PIOCPStruct = ^TIOCPStruct;

  EMemoryBuffer = class(Exception);
  ESocketError = class(Exception);

  TMemoryManager = class;
  TServerSocket = class;
  TSymmetricalSocket = class;

  TMemoryManager = class
  private
    {* 管理內存使用 *}
    FList: TList;
    {* 分配和釋放時候使用的鎖 *}
    FLock: TCriticalSection;
    {* 服務器 *}
    FServerSocket: TServerSocket;
    function GetCount: Integer;
    function GetIOCPStruct(AIndex: Integer): PIOCPStruct;
  public
    constructor Create(AServerSocket: TServerSocket; ACount: Integer); overload;
    constructor Create(AServerSocket: TServerSocket); overload;
    destructor Destroy; override;

    {* 分配內存使用權 *}
    function Allocate: PIOCPStruct;
    {* 釋放內存使用權 *}
    procedure Release(AValue: PIOCPStruct);
    property Server: TServerSocket read FServerSocket;
    property Count: Integer read GetCount;
    property Item[AIndex: Integer]: PIOCPStruct read GetIOCPStruct;
  end;

  {* 客服端鏈接服務器觸發此事件,如果要拒絕鏈接,把AConnect := False *}
  TOnBeforeConnect = procedure(ASymmIP: string; AConnect: Boolean) of object;
  {* 鏈接完成之后觸發此事件 *}
  TOnAfterConnect = procedure(ASymmetricalSocket: TSymmetricalSocket) of object;
  {* 斷開連接觸發事件 *}
  TOnAfterDisconnect = procedure(ASymmetricalSocket: TSymmetricalSocket) of object;
  {* 收到數據會觸發此事件 *}
  TOnDataEvent = procedure(ASymmetricalSocket: TSymmetricalSocket; AData: Pointer;
    ACount: Integer) of object;
  {* 錯誤觸發事件 *}
  TOnErrorEvent = procedure(AError: Integer; AErrorString: string; AInfo: string; var AHandleError: Boolean) of object;
  {* 服務器運行LOG *}
  TOnLog = procedure (ASocketEvent: TSocketEvent; AInfo: string) of object;

  {* 服務器,負責建立完成端口,管理內存和管理客服端,及Socket消息循環 *}
  TServerSocket = class
  private
    {* 內存管理 *}
    FMemory: TMemoryManager;
    {* 端口 *}
    FPort: Integer;
    {* 套接字 *}
    FSocket: TSocket;
    {* 完成端口句柄 *}
    FIOCPHandle: THandle;
    {* 消息循環句柄 *}
    FHandle: THandle;
    {* 對等的客服端 *}
    FClients: TList;
    {* 服務器運行線程 *}
    FThreads: TList;
    {* 監聽線程 *}
    FAcceptThread: TThread;
    {* 表示是否激活 *}
    FActive: Boolean;
    {* 鎖 *}
    FLock: TCriticalSection;
    {* 錯誤觸發事件 *}
    FOnError: TOnErrorEvent;
    {* 書寫LOG *}
    FOnLog: TOnLog;
    {* 接收連接事件 *}
    FOnBeforeConnect: TOnBeforeConnect;
    {* 連接成功之后的事件 *}
    FOnAfterConnect: TOnAfterConnect;
    {* 斷開連接事件 *}
    FOnAfterDisconnect: TOnAfterDisconnect;
    {* 接收數據 *}
    FOnRead: TOnDataEvent;

    procedure WndProc(var AMsg: TMessage);
    {* 激活 *}
    procedure Open;
    {* 關閉 *}
    procedure Close;
    {* 設置激活/關閉 *}
    procedure SetActive(AValue: Boolean);
    {* 觸發錯誤 *}
    function CheckError(AErrorCode: Integer = -1; AInfo: string = ''): Boolean;
    {* 觸發LOG *}
    procedure DoLog(ASocketEvent: TSocketEvent; AInfo: string = '');
    {* 設置端口 *}
    procedure SetPort(AValue: Integer);
    {* 注冊一個客服端,由于在另外一個線程中調用,需要加鎖 *}
    procedure RegisterClient(ASocket: TSymmetricalSocket);
    {* 反注冊一個客服端,由于在另外一個線程中調用,需要加鎖 *}
    procedure UnRegisterClient(ASocket: TSymmetricalSocket);
    {* 通過Socket句柄查找對等的TSymmetricalSocket *}
    function FindSymmClient(ASocket: TSocket): TSymmetricalSocket;
    {* 客服端關閉消息 *}
    procedure WMClientClose(var AMsg: TCMSocketMessage); message WM_CLIENTSOCKET;
    {* 連接時觸發的事件 *}
    function DoConnect(ASocket: TSocket): Boolean;
    {* 連接完成之后觸發事件 *}
    procedure DoAfterConnect(ASymSocket: TSymmetricalSocket);
    {* 連接斷開觸發事件 *}
    procedure DoDisConnect(ASymSocket: TSymmetricalSocket);
    {* 接收數據觸發的事件 *}
    procedure DoRead(ASymmetricalSocket: TSymmetricalSocket; AData: Pointer;
      ACount: Integer);
    {* 獲得客服端個數 *}
    function GetClientCount: Integer;
    function GetClient(const AIndex: Integer): TSymmetricalSocket;
  public
    constructor Create;
    destructor Destroy; override;
    {* 接收一個客服端,被接收線程調用 *}
    procedure AcceptClient;

    property Port: Integer read FPort write SetPort;
    property Socket: TSocket read FSocket;
    property Handle: THandle read FHandle;
    property Active: Boolean read FActive write SetActive;
    property MemoryManager: TMemoryManager read FMemory;
    {* 事件 *}
    property OnError: TOnErrorEvent read FOnError write FOnError;
    property OnLog: TOnLog read FOnLog write FOnLog;
    property OnRead: TOnDataEvent read FOnRead write FOnRead;
    property OnBeforeConnect: TOnBeforeConnect read FOnBeforeConnect write FOnBeforeConnect;
    property OnAfterConnect: TOnAfterConnect read FOnAfterConnect write FOnAfterConnect;
    property OnAfterDisConnect: TOnAfterDisconnect read FOnAfterDisconnect write FOnAfterDisconnect;
    property ClientCount: Integer read GetClientCount;
    property Client[const AIndex: Integer]: TSymmetricalSocket read GetClient;
  end;

  {* 接收數據、發送數據及管理分配的內存 *}
  TSymmetricalSocket = class
  private
    FSocket: TSocket;
    FServer: TServerSocket;
    FAssignMemory: TList;
    FRemoteAddress, FRemoteHost: string;
    FRemotePort: Integer;

    {* 準備接收數據 *}
    function PrepareRecv(AIOCPStruct: PIOCPStruct = nil): Boolean;
    {* 獲得完成端口內存塊使用權 *}
    function Allocate: PIOCPStruct;
    {* 處理接收的數據 *}
    function WorkBlock(AIOCPStruct: PIOCPStruct; ACount: DWORD): Integer;
    {* 獲得地方IP *}
    function GetRemoteIP: string;
    {* 獲得遠程機器名 *}
    function GetRemoteHost: string;
    {* 獲得遠程端口 *}
    function GetRemotePort: Integer;
  public
    constructor Create(ASvrSocket: TServerSocket; ASocket: TSocket);
    destructor Destroy; override;
    {* 發送數據 *}
    function Write(var ABuf; ACount: Integer): Integer;
    function WriteString(const AValue: string): Integer;

    property Socket: TSocket read FSocket;
    property RemoteAddress: string read GetRemoteIP;
    property RemoteHost: string read GetRemoteHost;
    property RemotePort: Integer read GetRemotePort;
  end;

  TSocketThread = class(TThread)
  private
    FServer: TServerSocket;
  public
    constructor Create(AServer: TServerSocket);
  end;

  TAcceptThread = class(TSocketThread)
  protected
    procedure Execute; override;
  end;

  TWorkThread = class(TSocketThread)
  protected
    procedure Execute; override;
  end;

implementation

uses
  RTLConsts;

const
 SHUTDOWN_FLAG = $FFFFFFFF;

{ TMemoryManager }

constructor TMemoryManager.Create(AServerSocket: TServerSocket;
  ACount: Integer);
var
  i: Integer;
  pIOCPData: PIOCPStruct;
begin
  inherited Create;
  FList := TList.Create;
  FLock := TCriticalSection.Create;
  for i := 1 to ACount do
  begin
    New(pIOCPData);
    FillChar(pIOCPData^, SizeOf(PIOCPStruct), 0);
    {* 下面兩句其實由FillChar已經完成,在這寫,只是為了強調 *}
    pIOCPData.Assigned := False;
    pIOCPData.Active := False;
    FList.Add(pIOCPData);
  end;
end;

function TMemoryManager.Allocate: PIOCPStruct;
var
  i: Integer;
begin
  FLock.Enter;
  try
    Result := nil;
    for i := 0 to FList.Count - 1 do
    begin
      Result := FList[i];
      if not Result.Assigned then
        Break;
    end;
    if (not Assigned(Result)) or (Result.Assigned) then
    begin
      New(Result);
      FList.Add(Result);
    end;
    FillChar(Result^, SizeOf(TIOCPStruct), 0);
    Result.Assigned := True;
    Result.Active := False;
  finally
    FLock.Leave;
  end;
end;

constructor TMemoryManager.Create(AServerSocket: TServerSocket);
begin
  Create(AServerSocket, 200);
end;

destructor TMemoryManager.Destroy;
var
  i: Integer;
begin
  for i := 0 to FList.Count - 1 do
    FreeMem(FList[i]);
  FList.Clear;
  FList.Free;
  FLock.Free;
  inherited;
end;

function TMemoryManager.GetCount: Integer;
begin
  Result := FList.Count;
end;

function TMemoryManager.GetIOCPStruct(AIndex: Integer): PIOCPStruct;
begin
  Result := nil;
  if (AIndex >= FList.Count) or (AIndex < 0) then
    EMemoryBuffer.CreateFmt(SListIndexError, [AIndex])
  else
    Result := FList[AIndex];
end;

procedure TMemoryManager.Release(AValue: PIOCPStruct);
begin
  FLock.Enter;
  try
    AValue.Assigned := False;
    AValue.Active := False;
  finally
    FLock.Leave;
  end;
end;

{ TServerSocket }

constructor TServerSocket.Create;
begin
  FMemory := TMemoryManager.Create(Self);
  FClients := TList.Create;
  FThreads := TList.Create;
  FSocket := INVALID_SOCKET;
  FLock := TCriticalSection.Create;

  FPort := 6666;
  FAcceptThread := nil;
  FIOCPHandle := 0;
  FHandle := AllocateHWnd(WndProc);
end;

destructor TServerSocket.Destroy;
begin
  //關閉完成端口
  SetActive(False);
  FThreads.Free;
  FClients.Free;
  DeallocateHWnd(FHandle);
  FMemory.Free;
  FLock.Free;
  inherited;
end;

procedure TServerSocket.Open;
var
  SystemInfo: TSystemInfo;
  i: Integer;
  Thread: TThread;
  Addr: TSockAddr;
  WSData: TWSAData;
begin
  try
    if WSAStartup($0202, WSData) <> 0 then
    begin
      raise ESocketError.Create('WSAStartup');
    end;
    DoLog(seInitIOPort);  //初始化完成端口
    FIOCPHandle := CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
    if FIOCPHandle = 0 then
      CheckError;

    DoLog(seInitThread); //初始化工作線程
    GetSystemInfo(SystemInfo);
    for i := 0 to SystemInfo.dwNumberOfProcessors * 2 -1 do
    begin
      Thread := TWorkThread.Create(Self);
      FThreads.Add(Thread);
    end;

    DoLog(seInitSocket); //建立套接字
    FSocket := WSASocket(PF_INET, SOCK_STREAM, 0, nil, 0, WSA_FLAG_OVERLAPPED);
    if FSocket = INVALID_SOCKET then CheckError;

    FillChar(Addr, SizeOf(TSockAddr), 0);
    Addr.sin_family := AF_INET;
    Addr.sin_port := htons(FPort);
    Addr.sin_addr.S_addr := htonl(INADDR_ANY);
    CheckError(bind(FSocket, @Addr, SizeOf(TSockAddr)), 'bind');

    DoLog(seListen);  //開始監聽
    CheckError(listen(FSocket, 5), 'listen');
    FAcceptThread := TAcceptThread.Create(Self);
  except
    on E: Exception do
    begin
      Close;
      CheckError(GetLastError, E.Message);
    end;
  end;
end;

procedure TServerSocket.Close;
var
  i: Integer;
  Thread: TThread;
begin
  try
    WSACleanup;
    DoLog(seUninitSocket);
    FAcceptThread.Terminate;
    if FSocket <> INVALID_SOCKET then
    begin
      closesocket(FSocket);
      FSocket := INVALID_SOCKET;
    end;

    DoLog(seUninitThread);
    for i := FThreads.Count - 1 downto 0 do
    begin
      Thread := FThreads[i];
      Thread.Terminate;
      PostQueuedCompletionStatus(FIOCPHandle, 0, 0, Pointer(SHUTDOWN_FLAG))
    end;
    FThreads.Clear;

    for i := FClients.Count - 1 downto 0 do
    begin
      TSymmetricalSocket(FClients[i]).Free;
    end;
    FClients.Clear;

    DoLog(seUninitIOPort);
    CloseHandle(FIOCPHandle);
    FIOCPHandle := 0;
  except
    on E: Exception do
    begin
      Close;
      CheckError(-1, E.Message);
    end;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
337p亚洲精品色噜噜| 久久蜜桃一区二区| 国产精品丝袜在线| 欧美日韩综合不卡| 高清久久久久久| 国产中文字幕精品| 蜜臀av性久久久久蜜臀av麻豆| 国产午夜三级一区二区三| 欧美午夜在线一二页| 精品一区二区三区在线视频| 国产精品久久久久一区| 久久亚洲一区二区三区四区| 欧美日本不卡视频| 91福利精品视频| 91在线视频免费观看| 成人高清免费观看| 国内外成人在线| 91黄色免费版| 欧美α欧美αv大片| 久久影院视频免费| 亚洲精品自拍动漫在线| 一区二区免费在线| 亚洲一区在线播放| 日韩精品电影在线| 精品夜夜嗨av一区二区三区| 91久久精品一区二区三| 久久这里只有精品首页| 午夜在线成人av| 精品午夜一区二区三区在线观看| 99精品视频中文字幕| 久久久午夜精品理论片中文字幕| 亚洲另类一区二区| va亚洲va日韩不卡在线观看| 99精品一区二区| 国产三级欧美三级日产三级99| 欧美二区三区91| 国产视频一区二区在线观看| 麻豆91在线看| 久久精品亚洲乱码伦伦中文| 国产乱码精品一区二区三区av | 国产91综合网| 国产女人18毛片水真多成人如厕| 国内成+人亚洲+欧美+综合在线| 4438x亚洲最大成人网| 肉丝袜脚交视频一区二区| 日韩一区二区不卡| 亚洲一区二区三区四区不卡| 欧美日韩一区在线| 激情成人午夜视频| 中文字幕一区二区三区在线观看 | 国产suv精品一区二区883| 自拍偷拍欧美精品| 国产又黄又大久久| 91精品国产欧美日韩| 亚洲一区在线观看网站| 91精品国产高清一区二区三区蜜臀 | 亚洲欧洲性图库| 欧美一级精品在线| 99re这里只有精品视频首页| 亚洲一区二区三区在线播放| 日韩视频一区二区在线观看| 91亚洲大成网污www| 亚洲欧洲日产国产综合网| 91精品国产综合久久久久久久久久| 国产成人在线看| 日韩毛片精品高清免费| 国产调教视频一区| 精品少妇一区二区三区视频免付费| 91捆绑美女网站| av高清不卡在线| 99综合影院在线| 一本一道波多野结衣一区二区| 一区二区三区 在线观看视频| 亚洲欧洲三级电影| 亚洲色图欧美激情| 欧美国产成人精品| 在线观看免费成人| 日产欧产美韩系列久久99| 欧美成人a视频| 日韩精品自拍偷拍| 99精品国产视频| 色综合色狠狠综合色| 99视频在线观看一区三区| 波多野结衣亚洲一区| 色综合色综合色综合| 97久久精品人人做人人爽50路| 成人毛片在线观看| 久久草av在线| 午夜精品aaa| 亚洲人吸女人奶水| 国产精品欧美综合在线| 亚洲免费观看高清完整版在线观看| 日韩美女啊v在线免费观看| 亚洲国产精品久久一线不卡| 久久一区二区三区四区| 亚洲视频你懂的| 日本欧美在线观看| 国产一区二区美女| 91福利资源站| 国产欧美综合在线观看第十页| 亚洲婷婷综合色高清在线| 亚洲一区视频在线观看视频| 精品一区二区三区在线观看| 99久久精品免费看国产免费软件| 欧美欧美午夜aⅴ在线观看| 国产精品欧美综合在线| 麻豆久久久久久久| 欧美三级乱人伦电影| 中文字幕乱码一区二区免费| 美女免费视频一区| 欧美视频一二三区| 亚洲欧美偷拍三级| 成人免费视频播放| 国产欧美一区二区精品婷婷| 日本少妇一区二区| 日韩一区二区三区在线观看| 一区二区三区四区五区视频在线观看 | 久久66热re国产| 日韩一区二区在线看片| 亚洲二区视频在线| 欧美性猛交一区二区三区精品| 中文字幕的久久| av不卡一区二区三区| 国产精品久线在线观看| thepron国产精品| 中文字幕在线一区二区三区| 成人在线视频一区| 亚洲天堂福利av| 色哟哟国产精品| 视频一区二区中文字幕| 欧美一级黄色片| 国产成人aaa| 亚洲大型综合色站| 精品久久五月天| 国产精品99久久久久| 一区二区三区在线免费视频 | 亚洲精品ww久久久久久p站| 91精品福利视频| 日本一区中文字幕| 国产精品久久久久久久久免费樱桃| 91美女在线看| 精品一区二区三区香蕉蜜桃| 中文字幕巨乱亚洲| 欧美日韩免费高清一区色橹橹| 蜜臀久久99精品久久久画质超高清| 久久免费精品国产久精品久久久久| 粉嫩aⅴ一区二区三区四区五区| 亚洲最大色网站| 欧美日韩国产精品成人| 一卡二卡欧美日韩| www.亚洲精品| 1000部国产精品成人观看| 国产v日产∨综合v精品视频| 麻豆成人久久精品二区三区红| 久久国产精品区| 国产夫妻精品视频| heyzo一本久久综合| 色先锋资源久久综合| 一本色道久久综合狠狠躁的推荐| 极品少妇xxxx精品少妇偷拍| 亚洲国产wwwccc36天堂| 亚洲激情男女视频| 亚洲视频小说图片| 亚洲黄一区二区三区| 亚洲欧美日韩国产成人精品影院 | 欧美一级在线观看| 欧美一区二区三区爱爱| 欧美日韩不卡视频| 日韩免费观看高清完整版| 欧美一区日韩一区| 久久久亚洲国产美女国产盗摄| 欧美成人a视频| 国产精品毛片a∨一区二区三区| 国产嫩草影院久久久久| 中文在线资源观看网站视频免费不卡| 国产欧美一区二区三区沐欲 | 精品视频免费在线| 欧美在线观看一区| 精品国产自在久精品国产| 成人丝袜高跟foot| 欧美日韩1区2区| 亚洲欧洲综合另类在线| 精品一区在线看| 欧美日韩综合在线免费观看| 一区在线观看免费| 久久99精品久久久久久国产越南| 色先锋aa成人| 久久九九99视频| 久久国产乱子精品免费女| eeuss鲁一区二区三区| 欧美mv日韩mv国产网站| 亚洲成人动漫在线免费观看| 成人av电影在线播放| 2021国产精品久久精品| 视频一区二区三区入口| 91福利在线观看| 一区二区三区精品在线| 在线精品亚洲一区二区不卡| 中文字幕在线观看不卡| 9i在线看片成人免费|