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

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

?? svrsocket,cltsocket控件源碼.htm

?? ServerSocket,ClientSocket控件源碼,講述內部實現原理
?? HTM
?? 第 1 頁 / 共 3 頁
字號:
      <br>
      begin<br>
      <br>
        FActive := False;<br> 
      <br>
        if Assigned(FOnDisconnect) then FOnDisconnect(Self, Socket);<br> 
      <br>
      end;<br>
      <br>
    seAccept: if Assigned(FOnAccept) then FOnAccept(Self, Socket);<br> 
      <br>
    seRead: if Assigned(FOnRead) then FOnRead(Self, Socket);<br> 
      <br>
    seWrite: if Assigned(FOnWrite) then FOnWrite(Self, Socket);<br> 
      <br>
  end;<br>
      <br>
      end;<br>
      <br>
      其中FonAccept等這些都是TCusotmSocket的成員,都是TSocketNotifyEvent類型的,TCustomSocket還通過下面這些屬性,使該類擁有了這些事件處理的能力:<br>
      <br>
      property OnLookup: TSocketNotifyEvent read FOnLookup write FOnLookup;<br> 
      <br>
    property OnConnecting: TSocketNotifyEvent read FOnConnecting write FOnConnecting;<br> 
      <br>
    property OnConnect: TSocketNotifyEvent read FOnConnect write FOnConnect;<br> 
      <br>
    property OnDisconnect: TSocketNotifyEvent read FOnDisconnect write FOnDisconnect;<br> 
      <br>
    property OnListen: TSocketNotifyEvent read FOnListen write FOnListen;<br> 
      <br>
    property OnAccept: TSocketNotifyEvent read FOnAccept write FOnAccept;<br> 
      <br>
    property OnRead: TSocketNotifyEvent read FOnRead write FOnRead;<br> 
      <br>
      property OnWrite: TSocketNotifyEvent read FOnWrite write FOnWrite;<br> 
      <br>
      而上面的Event實現,我們可以看到它是根據SocketEvent的類型來調用相應的事件指針的,而它的子類ServerSocket和ClientSocket也擁有了這些事件的處理能力,到這里我們終于明白了,它們的事件是怎么樣出來的,但如果想得知這些事件是怎么觸發的,還要看這一句:Socket.OnSocketEvent,OnSocketEvent到后面再說,這里先略。<br>
      <br>
      錯誤處理事件原理上也是一樣,到后面再說。<br>
      <br>
      <br>
      <br>
      好了,到這里第一步解讀完畢,我們所知道的ServerSocket創建之后所完成事件就是初始化Socket DLL,并指定好事件處理的方法指針和錯誤處理的方法指針。我們接下來看第二步。<br> 
      <br>
      <br>
      <br>
      <br>
      <br>
      2.我們創建完ServerSocket后,下步要做什么呢,當然是指定端口啦,然后Open開始監視啦,這個過程會觸發一些事件,我們正好看看這些事件是怎么樣發生的。<br>
      <br>
      由于這一次操作是非阻塞方式的,所以ServerType默認為stNonBlocking,我們開始設置Port,這個屬性的聲明在哪里,這個屬性一直到跟蹤祖先類AbstractSocket中去,因為無論客戶端和服務端都是要設置端口的,所以理所當然要封裝到最高層的類去了,以讓它的子類擁有這些屬性:<br>
      <br>
      property Port: Integer read FPort write SetPort;<br> 
      <br>
      再看看SetPort方法:<br>
      <br>
      (21)<br>
      <br>
      procedure TAbstractSocket.SetPort(Value: Integer);<br> 
      <br>
      begin<br>
      <br>
  if FPort &lt;> Value then<br> 
      <br>
  begin<br>
      <br>
    if not (csLoading in ComponentState) and FActive then<br> 
      <br>
      raise ESocketError.CreateRes(@sCantChangeWhileActive);<br> 
      <br>
    FPort := Value;<br> 
      <br>
  end;<br>
      <br>
      end;<br>
      <br>
      if not (csLoading in ComponentState) and FActive then<br> 
      <br>
      raise ESocketError.CreateRes(@sCantChangeWhileActive);<br> 
      <br>
      這一句是防止你在運行時改變端口,最后才將值賦給FPort。<br>
      <br>
      好了,設置后Port后,就要Open了,開始監視客戶端了。<br>
      <br>
      監視有兩個方式,一種是直接設Active屬性為True,一種直接調用Open方法。<br>
      <br>
      其中Open方法如下:<br>
      <br>
      procedure TAbstractSocket.Open;<br> 
      <br>
      begin<br>
      <br>
  Active := True;<br> 
      <br>
      end;<br>
      <br>
      它還是用到了屬性Active,所以我們可以集中來討論Active屬性。<br>
      <br>
      property Active: Boolean read FActive write SetActive;<br> 
      <br>
      看看SetActive:<br>
      <br>
      (22)<br>
      <br>
      procedure TAbstractSocket.SetActive(Value: Boolean);<br> 
      <br>
      begin<br>
      <br>
  if Value &lt;> FActive then<br> 
      <br>
  begin<br>
      <br>
    if (csDesigning in ComponentState) or (csLoading in ComponentState) then<br> 
      <br>
      FActive := Value;<br> 
      <br>
    if not (csLoading in ComponentState) then<br> 
      <br>
      DoActivate(Value);<br>
      <br>
  end;<br>
      <br>
      end;<br>
      <br>
      我們可以這樣認為,當設計時就直接設FActive,當運行時,就調用DoActivate(Value);<br>
      <br>
      而TAbstractSocket覆蓋了Loaded方法,則當窗體開始運行,從Form文件中開始流入時,也調用了DoActive方法。<br>
      <br>
      再看DoActive了:<br>
      <br>
      (221)<br>
      <br>
      procedure DoActivate(Value: Boolean); virtual; abstract;又是一種抽象方法,得到它的子類去看了,在它的子類TCustomServerSocket找到這個方法:<br> 
      <br>
      procedure TCustomServerSocket.DoActivate(Value: Boolean);<br> 
      <br>
      begin<br>
      <br>
  if (Value &lt;> FServerSocket.Connected) and not (csDesigning in ComponentState) then<br> 
      <br>
  begin<br>
      <br>
    if FServerSocket.Connected then<br> 
      <br>
      FServerSocket.Disconnect(FServerSocket.SocketHandle)<br>
      <br>
    else FServerSocket.Listen(FHost, FAddress, FService, FPort, SOMAXCONN);<br> 
      <br>
  end;<br>
      <br>
      end;<br>
      <br>
      可以這樣理解,不在設計時,當Value不等它的成員FServerSocket.Connected時(我們可先認為這個表示當前的監聽狀態),而如果此時FServerSocket.Connected為True,則表示Value為False,,那么這時要斷開連接,調用FServerSocket.Disconnect(FServerSocket.SocketHandle)<br>
      <br>
      很多時候ServerSocket都是調用它的成員FServerSocket來完成操作的,這一點我已經看到了,下面還有更多這樣的情況。否則,則Value為True,調用<br>
      <br>
      FServerSocket.Listen(FHost, FAddress, FService, FPort, SOMAXCONN);來開始進行監視。好的,現在我們就要打開FServerSocket的源碼,看看它是怎么樣完成斷開連接和開始連接的了。<br> 
      <br>
      先看開始監聽的:<br>
      <br>
      (2211)<br>
      <br>
      procedure TServerWinSocket.Listen(var Name, Address, Service: string; Port: Word;<br> 
      <br>
  QueueSize: Integer);<br> 
      <br>
      begin<br>
      <br>
  inherited Listen(Name, Address, Service, Port, QueueSize, ServerType = stThreadBlocking);<br> 
      <br>
  if FConnected and (ServerType = stThreadBlocking) then<br> 
      <br>
    FServerAcceptThread := TServerAcceptThread.Create(False, Self);<br> 
      <br>
      end;<br>
      <br>
      這里調用其父類的Listen方法,如果它是阻塞方式的,則還要生成一個線程類,由于我用的非阻塞方式,所以暫不去理它,看看他的父類的Listen方法:<br>
      <br>
      (22111)<br>
      <br>
      procedure TCustomWinSocket.Listen(const Name, Address, Service: string; Port: Word;<br> 
      <br>
  QueueSize: Integer; Block: Boolean);<br> 
      <br>
      begin<br>
      <br>
  if FConnected then raise ESocketError.CreateRes(@sCannotListenOnOpen);<br> 
      <br>
  FSocket := socket(PF_INET, SOCK_STREAM, IPPROTO_IP);<br> 
      <br>
  if FSocket = INVALID_SOCKET then raise ESocketError.CreateRes(@sCannotCreateSocket);<br> 
      <br>
  try<br>
      <br>
    Event(Self, seLookUp);<br> 
      <br>
    if Block then<br> 
      <br>
    begin<br>
      <br>
      FAddr := InitSocket(Name, Address, Service, Port, False);<br> 
      <br>
      DoListen(QueueSize);<br>
      <br>
    end else<br> 
      <br>
      AsyncInitSocket(Name, Address, Service, Port, QueueSize, False);<br> 
      <br>
  except<br>
      <br>
    Disconnect(FSocket);<br>
      <br>
    raise;<br>
      <br>
  end;<br>
      <br>
      end;<br>
      <br>
      這里第一句重要函數出現了:<br>
      <br>
      FSocket := socket(PF_INET, SOCK_STREAM, IPPROTO_IP);<br> 
      <br>
      記得上面Fsockeet曾被賦過值嗎,是INVALID_SOCKET;,而這里終于被替回了一個可用的套接字了。<br>
      <br>
      第二個重要的函數:Event(Self, seLookUp);可以先猜測這個方法最終于會調用事件指針,等一下再看。<br> 
      <br>
      接下來判斷Block的值,回頭看看這一句:<br>
      <br>
      inherited Listen(Name, Address, Service, Port, QueueSize, ServerType = stThreadBlocking);<br> 
      <br>
      如果為阻塞方式,則為True,否則為False,非阻塞為這時為False,調用下方法:<br>
      <br>
      AsyncInitSocket(Name, Address, Service, Port, QueueSize, False);<br> 
      <br>
      好了,再看一下Even吧:<br>
      <br>
      (221111)<br>
      <br>
      procedure TCustomWinSocket.Event(Socket: TCustomWinSocket; SocketEvent: TSocketEvent);<br> 
      <br>
      begin<br>
      <br>
  if Assigned(FOnSocketEvent) then FOnSocketEvent(Self, Socket, SocketEvent);<br> 
      <br>
      end;<br>
      <br>
      不出所料,調用事件指針了,這時ServerSocket的事件就會觸發了,回過頭去看看,<br>
      <br>
      seLookup: if Assigned(FOnLookup) then FOnLookup(Self, Socket);<br> 
      <br>
      這里CustomSocket的OnLookup事件發生,但ServerSocket并沒有顯化它,ClientSocket就有這個事件。<br>
      <br>
      按我們所設的方式,接下來要調用如下函數了(另外一些方法以后再說):<br>
      <br>
      AsyncInitSocket(Name, Address, Service, Port, QueueSize, False);<br> 
      <br>
      這函數很大,但所用到的技巧也非常精彩,得好好分析它:&nbsp;<br>
      <br>
      (221112)<br>
      <br>
      procedure TCustomWinSocket.AsyncInitSocket(const Name, Address,<br> 
      <br>
  Service: string; Port: Word; QueueSize: Integer; Client: Boolean);<br> 
      <br>
      var<br>
      <br>
  ErrorCode: Integer;<br> 
      <br>
      begin<br>
      <br>
  try<br>
      <br>
    case FLookupState of<br> 
      <br>
      lsIdle:<br>
      <br>
        begin<br>
      <br>
          if not Client then<br> 
      <br>
          begin<br>
      <br>
            FLookupState := lsLookupAddress;<br> 
      <br>
            FAddr.sin_addr.S_addr := INADDR_ANY;<br> 
      <br>
          //下面的情況到客戶端時才會用到<br>
      <br>
          end else if Name &lt;> '' then<br> 
      <br>
          begin<br>
      <br>
            if FGetHostData = nil then<br> 
      <br>
              FGetHostData := AllocMem(MAXGETHOSTSTRUCT);<br> 
      <br>
         FLookupHandle := WSAAsyncGetHostByName(Handle, CM_LOOKUPCOMPLETE,<br> 
      <br>
              PChar(Name), FGetHostData, MAXGETHOSTSTRUCT);<br> 
      <br>
            CheckSocketResult(Ord(FLookupHandle = 0), 'WSAASyncGetHostByName');<br> 
      <br>
            FService := Service;<br> 
      <br>
            FPort := Port;<br> 
      <br>
            FQueueSize := QueueSize;<br> 
      <br>
            FClient := Client;<br> 
      <br>
            FLookupState := lsLookupAddress;<br> 
      <br>
            Exit;<br>
      <br>
          end else if Address &lt;> '' then<br> 
      <br>
          begin<br>
      <br>
            FLookupState := lsLookupAddress;<br> 
      <br>
            FAddr.sin_addr.S_addr := inet_addr(PChar(Address));<br> 
      <br>
          end else<br> 
      <br>
          begin<br>
      <br>
            ErrorCode := 1110;<br> 
      <br>
            Error(Self, eeLookup, ErrorCode);<br> 
      <br>
            Disconnect(FSocket);<br>
      <br>
            if ErrorCode &lt;> 0 then<br> 
      <br>
              raise ESocketError.CreateRes(@sNoAddress);<br> 
      <br>
            Exit;<br>
      <br>
          end;<br>
      <br>
        end;<br>
      <br>
      lsLookupAddress:<br>
      <br>
        begin<br>
      <br>
          if Service &lt;> '' then<br> 
      <br>
          begin<br>
      <br>
            if FGetHostData = nil then<br> 
      <br>
              FGetHostData := AllocMem(MAXGETHOSTSTRUCT);<br> 
      <br>
         FLookupHandle := WSAASyncGetServByName(Handle, CM_LOOKUPCOMPLETE,<br> 
      <br>
              PChar(Service), 'tcp' , FGetHostData, MAXGETHOSTSTRUCT);<br> 
      <br>
            CheckSocketResult(Ord(FLookupHandle = 0), 'WSAASyncGetServByName');<br> 
      <br>
            FLookupState := lsLookupService;<br> 
      <br>
            Exit;<br>
      <br>
          end else<br> 
      <br>
          begin<br>
      <br>
            FLookupState := lsLookupService;<br> 
      <br>
            FAddr.sin_port := htons(Port);<br> 
      <br>
          end;<br>
      <br>
        end;<br>
      <br>
      lsLookupService:<br>
      <br>
        begin<br>
      <br>
          FLookupState := lsIdle;<br> 
      <br>
          if Client then<br> 
      <br>
            DoOpen<br>

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美一区二区三区免费在线看| 欧美亚洲动漫精品| 日韩精品电影在线观看| 亚洲男同性恋视频| 最新国产成人在线观看| 亚洲欧洲美洲综合色网| 亚洲欧美另类在线| 一区二区三区在线不卡| 亚洲成人一二三| 日韩黄色免费电影| 久久er99热精品一区二区| 蜜桃在线一区二区三区| 国产一区二区在线看| 国产福利一区在线| 色老综合老女人久久久| 欧美色综合影院| 欧美一级淫片007| 国产午夜亚洲精品不卡| 亚洲欧美一区二区三区极速播放| 一区二区不卡在线视频 午夜欧美不卡在| 亚洲欧洲综合另类| 轻轻草成人在线| 国产丶欧美丶日本不卡视频| 色综合久久久久久久久| 欧美性猛交xxxx乱大交退制版| 91麻豆精品国产91久久久久久久久 | 日韩免费高清电影| 中文字幕不卡的av| 一区二区三区欧美| 国产在线精品国自产拍免费| 成人av网址在线| 欧美日韩国产片| 欧美激情一区二区三区四区| 午夜精品久久久久| 国产成人夜色高潮福利影视| 欧美在线制服丝袜| 中文字幕欧美区| 肉丝袜脚交视频一区二区| 国产精品77777| 欧美一级久久久久久久大片| 中文在线免费一区三区高中清不卡| 亚洲国产另类av| 福利一区福利二区| 欧美乱熟臀69xxxxxx| 日本一二三不卡| 天天亚洲美女在线视频| 成人av动漫网站| 2020国产成人综合网| 五月天婷婷综合| 91女人视频在线观看| 日韩精品一区二区三区在线播放| 一区二区在线免费观看| 国产精品88888| 精品免费视频.| 日韩va亚洲va欧美va久久| 91久久奴性调教| 国产精品久久国产精麻豆99网站 | 麻豆极品一区二区三区| 日本精品视频一区二区三区| 久久久久亚洲蜜桃| 免费在线看成人av| 欧美喷水一区二区| 一区二区三区影院| 成人ar影院免费观看视频| 精品久久国产97色综合| 午夜久久福利影院| 欧美色图在线观看| 一个色综合网站| 91久久香蕉国产日韩欧美9色| 中文字幕av资源一区| 大尺度一区二区| 国产视频在线观看一区二区三区| 日韩高清不卡一区二区三区| 欧美日韩国产精品成人| 亚洲一区二区免费视频| 欧美视频中文字幕| 亚洲国产精品久久人人爱| 在线国产亚洲欧美| 亚洲国产成人av| 555www色欧美视频| 免费观看日韩电影| 欧美v国产在线一区二区三区| 美腿丝袜在线亚洲一区| 日韩女同互慰一区二区| 久久99精品国产91久久来源| 2022国产精品视频| 国产在线一区二区| 中文字幕高清一区| 欧洲亚洲国产日韩| 青青草原综合久久大伊人精品优势| 欧美日韩在线综合| 老汉av免费一区二区三区| 精品国产髙清在线看国产毛片| 精品一二三四区| 国产精品麻豆网站| 欧美亚洲丝袜传媒另类| 秋霞影院一区二区| 中文字幕一区二区三区在线播放| 色悠久久久久综合欧美99| 五月天精品一区二区三区| 欧美成人性福生活免费看| 成人综合婷婷国产精品久久蜜臀 | 欧美一区二区不卡视频| 精品在线播放午夜| 中文字幕中文乱码欧美一区二区| 91黄色激情网站| 极品少妇一区二区三区精品视频| 国产欧美日韩在线观看| 91福利国产精品| 加勒比av一区二区| 亚洲国产一区二区视频| 久久免费电影网| 欧美日韩综合色| 丁香亚洲综合激情啪啪综合| 亚洲bt欧美bt精品| 国产精品欧美极品| 日韩视频在线你懂得| 99国产欧美另类久久久精品| 麻豆成人av在线| 亚洲一区二区精品久久av| 国产亚洲人成网站| 在线综合视频播放| 色哟哟在线观看一区二区三区| 久久福利资源站| 亚洲成在人线免费| 亚洲欧美日韩久久| 久久久久久久免费视频了| 欧美蜜桃一区二区三区| jlzzjlzz国产精品久久| 另类欧美日韩国产在线| 亚洲电影第三页| 日韩一区欧美小说| 国产精品网曝门| 久久这里只精品最新地址| 欧美精品 日韩| 日本久久一区二区| 91丨国产丨九色丨pron| 国产精品一区二区三区网站| 久久精品国产精品亚洲精品| 亚洲高清免费观看| 色一区在线观看| 日本一区二区三区高清不卡| 欧美日韩国产另类一区| 日本伦理一区二区| 在线一区二区观看| 丁香婷婷深情五月亚洲| 韩国女主播成人在线| 日韩avvvv在线播放| 亚洲五码中文字幕| 丝袜美腿亚洲一区二区图片| 亚洲小少妇裸体bbw| 亚洲国产精品一区二区久久恐怖片 | 欧美久久一二三四区| 色一区在线观看| 欧美影院精品一区| 91福利国产成人精品照片| 在线观看av一区| 欧美日韩成人在线一区| 91精品国产91综合久久蜜臀| 欧美精品三级日韩久久| 日韩一区国产二区欧美三区| 91精品国产欧美一区二区成人| 欧美精品久久99久久在免费线| 欧美日韩免费在线视频| 欧美精品 国产精品| 欧美一区二区成人| 精品国产三级电影在线观看| 久久久久免费观看| 国产精品国产三级国产三级人妇 | 韩国三级电影一区二区| 国产精品一区二区黑丝| 高清国产午夜精品久久久久久| 成人av在线播放网址| 91久久香蕉国产日韩欧美9色| 欧美日韩精品电影| 精品处破学生在线二十三| 久久新电视剧免费观看| 中文字幕一区二区三区蜜月 | 国产69精品一区二区亚洲孕妇| 国产成人综合在线播放| 色婷婷国产精品久久包臀| 欧美精品精品一区| 国产欧美精品区一区二区三区 | 国产精品久久毛片av大全日韩| 亚洲欧美日本韩国| 久久国产精品72免费观看| 不卡欧美aaaaa| 777xxx欧美| 国产精品对白交换视频| 日韩在线一二三区| 不卡电影免费在线播放一区| 欧美撒尿777hd撒尿| 国产日产欧产精品推荐色| 夜夜精品浪潮av一区二区三区| 久久国产尿小便嘘嘘| 色婷婷久久久综合中文字幕| 久久综合成人精品亚洲另类欧美 | 亚洲va欧美va人人爽| 国产不卡视频在线观看| 欧美一区二区三区在线观看视频|