转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
ServerSocket,ClientSocket控件源码阅读笔记         ★★★★

ServerSocket,ClientSocket控件源码阅读笔记

作者:闵涛 文章来源:闵涛的学习笔记 点击数:7769 更新时间:2009/4/23 18:28:00
Active属性为True,一种直接调用Open方法。

其中Open方法如下:

procedure TAbstractSocket.Open;

begin

  Active := True;

end;

它还是用到了属性Active,所以我们可以集中来讨论Active属性。

property Active: Boolean read FActive write SetActive;

看看SetActive:

(22

procedure TAbstractSocket.SetActive(Value: Boolean);

begin

  if Value <> FActive then

  begin

    if (csDesigning in ComponentState) or (csLoading in ComponentState) then

      FActive := Value;

    if not (csLoading in ComponentState) then

      DoActivate(Value);

  end;

end;

我们可以这样认为,当设计时就直接设FActive,当运行时,就调用DoActivate(Value);

而TAbstractSocket覆盖了Loaded方法,则当窗体开始运行,从Form文件中开始流入时,也调用了DoActive方法。

再看DoActive了:

(221

procedure DoActivate(Value: Boolean); virtual; abstract;又是一种抽象方法,得到它的子类去看了,在它的子类TCustomServerSocket找到这个方法:

procedure TCustomServerSocket.DoActivate(Value: Boolean);

begin

  if (Value <> FServerSocket.Connected) and not (csDesigning in ComponentState) then

  begin

    if FServerSocket.Connected then

      FServerSocket.Disconnect(FServerSocket.SocketHandle)

    else FServerSocket.Listen(FHost, FAddress, FService, FPort, SOMAXCONN);

  end;

end;

可以这样理解,不在设计时,当Value不等它的成员FServerSocket.Connected时(我们可先认为这个表示当前的监听状态),而如果此时FServerSocket.Connected为True,则表示Value为False,,那么这时要断开连接,调用FServerSocket.Disconnect(FServerSocket.SocketHandle)

很多时候ServerSocket都是调用它的成员FServerSocket来完成操作的,这一点我已经看到了,下面还有更多这样的情况。否则,则Value为True,调用

FServerSocket.Listen(FHost, FAddress, FService, FPort, SOMAXCONN);来开始进行监视。好的,现在我们就要打开FServerSocket的源码,看看它是怎么样完成断开连接和开始连接的了。

先看开始监听的:

(2211

procedure TServerWinSocket.Listen(var Name, Address, Service: string; Port: Word;

  QueueSize: Integer);

begin

  inherited Listen(Name, Address, Service, Port, QueueSize, ServerType = stThreadBlocking);

  if FConnected and (ServerType = stThreadBlocking) then

    FServerAcceptThread := TServerAcceptThread.Create(False, Self);

end;

这里调用其父类的Listen方法,如果它是阻塞方式的,则还要生成一个线程类,由于我用的非阻塞方式,所以暂不去理它,看看他的父类的Listen方法:

(22111

procedure TCustomWinSocket.Listen(const Name, Address, Service: string; Port: Word;

  QueueSize: Integer; Block: Boolean);

begin

  if FConnected then raise ESocketError.CreateRes(@sCannotListenOnOpen);

  FSocket := socket(PF_INET, SOCK_STREAM, IPPROTO_IP);

  if FSocket = INVALID_SOCKET then raise ESocketError.CreateRes(@sCannotCreateSocket);

  try

    Event(Self, seLookUp);

    if Block then

    begin

      FAddr := InitSocket(Name, Address, Service, Port, False);

      DoListen(QueueSize);

    end else

      AsyncInitSocket(Name, Address, Service, Port, QueueSize, False);

  except

    Disconnect(FSocket);

    raise;

  end;

end;

这里第一句重要函数出现了:

FSocket := socket(PF_INET, SOCK_STREAM, IPPROTO_IP);

记得上面Fsockeet曾被赋过值吗,是INVALID_SOCKET;,而这里终于被替回了一个可用的套接字了。

第二个重要的函数:Event(Self, seLookUp);可以先猜测这个方法最终于会调用事件指针,等一下再看。

接下来判断Block的值,回头看看这一句:

inherited Listen(Name, Address, Service, Port, QueueSize, ServerType = stThreadBlocking);

如果为阻塞方式,则为True,否则为False,非阻塞为这时为False,调用下方法:

AsyncInitSocket(Name, Address, Service, Port, QueueSize, False);

好了,再看一下Even吧:

(221111

procedure TCustomWinSocket.Event(Socket: TCustomWinSocket; SocketEvent: TSocketEvent);

begin

  if Assigned(FOnSocketEvent) then FOnSocketEvent(Self, Socket, SocketEvent);

end;

不出所料,调用事件指针了,这时ServerSocket的事件就会触发了,回过头去看看,

seLookup: if Assigned(FOnLookup) then FOnLookup(Self, Socket);

这里CustomSocket的OnLookup事件发生,但ServerSocket并没有显化它,ClientSocket就有这个事件。

按我们所设的方式,接下来要调用如下函数了(另外一些方法以后再说):

AsyncInitSocket(Name, Address, Service, Port, QueueSize, False);

这函数很大,但所用到的技巧也非常精彩,得好好分析它:

(221112

procedure TCustomWinSocket.AsyncInitSocket(const Name, Address,

  Service: string; Port: Word; QueueSize: Integer; Client: Boolean);

var

  ErrorCode: Integer;

begin

  try

    case FLookupState of

      lsIdle:

        begin

          if not Client then

         

上一页  [1] [2] [3] [4] [5] [6] [7] [8] [9]  下一页


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台