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

ServerSocket,ClientSocket控件源码阅读笔记

作者:闵涛 文章来源:闵涛的学习笔记 点击数:7768 更新时间:2009/4/23 18:28:00
bsp;      FD_CLOSE: Disconnect(Socket);

        FD_READ: Read(Socket);

        FD_WRITE: Write(Socket);

        FD_ACCEPT: Accept(Socket);//这个很特殊

      end;

end;

呵,又是一个大函数,不过理解起来倒是容易多了,先检查有没有错误,如果有就调用Error(Self, ErrorEvent, ErrorCode);如果没有,就根据相应标识,调用相就的函数,其实我们已经可以确定,像Read这些内部一定会调用Event,再由Event调用

FOnSocketEvent(Self, Socket, SocketEvent);,这样才能使得ServerSocket这些外部的类获得事件(上面已经说到它们是怎么把事件关联起来的了)。

而源代码中确实也是这样的,这里只列出一个read,其他的一样:

procedure TCustomWinSocket.Read(Socket: TSocket);

begin

  if (FSocket = INVALID_SOCKET) or (Socket <> FSocket) then Exit;

  Event(Self, seRead);

end;

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

begin

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

end;

 

完了吧,可惜还没有,回到上面的函数去,发现还有一个方法没有分析:

FServerSocket.Disconnect(FServerSocket.SocketHandle)可是按我们流程,还不会调用到它,所以这里暂不提它。

 

好了,第二步就这样结束了,再说下去,我自己也晕了。不过我们知道了这一步所完成的任务:连接一个监听的套接字,并设定好了事件方法指针,在适当的时机会调用适当的事件处理函数。真的得谢谢Delphi为我们做了这么多的事,使我们在使用的时候感觉到是如此的简单。

 

 

3.程序执行到这里,得看看ClientSocket吧,有了上面的分析,下面的分析都会简单得多:

constructor TClientSocket.Create(AOwner: TComponent);

begin

  inherited Create(AOwner);

  FClientSocket := TClientWinSocket.Create(INVALID_SOCKET);

  InitSocket(FClientSocket);

end;

没有什么值得讨论的FClientSocket也是继承父类的构造方法,上面已经说过了。

接设置Port,Address等,都是到祖先类设置,没有什么好说的,最后一句是

Active:=true;

上面的讨论已经知道,它最后会调用ClientSocket的覆盖方法:

procedure TClientSocket.DoActivate(Value: Boolean);

begin

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

  begin

    if FClientSocket.Connected then

      FClientSocket.Disconnect(FClientSocket.FSocket)

    else FClientSocket.Open(FHost, FAddress, FService, FPort, ClientType = ctBlocking);

  end;

end;

这里的Value为True,则调用

FClientSocket.Open(FHost, FAddress, FService, FPort, ClientType = ctBlocking);

去看看吧:

procedure TCustomWinSocket.Open(const Name, Address, Service: string; Port: Word; Block: Boolean);

begin

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

  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, True);

      DoOpen;

    end else

      AsyncInitSocket(Name, Address, Service, Port, 0, True);

  except

    Disconnect(FSocket);

    raise;

  end;

end;

没什么特别之处,以我们设置的方式,也一样调用AsyncInitSocket,同样也是完成Socket的设置

再回去看看第2步中的代码吧,而它的Client参数是设为True,所以最后的一定会调用:

DoOpen:

procedure TCustomWinSocket.DoOpen;

begin

  DoSetASyncStyles;

  Event(Self, seConnecting);

  CheckSocketResult(WinSock.connect(FSocket, FAddr, SizeOf(FAddr)), ''''connect'''');

  FLookupState := lsIdle;

  if not (asConnect in FAsyncStyles) then

  begin

    FConnected := FSocket <> INVALID_SOCKET;

    Event(Self, seConnect);

  end;

end;

和上面说到的Dolisten简直像极了,这里也没有必多说了。我们已经可以向更加简单的第四步进发了。

 

 

4.  ClientSocket向服务端连接后,WinSock会向服务端发送一个事件,,而上面已经过了事件获取函数:CMSocketMessage

其中的消息标识码是:FD_ACCEPT,所以会调用Accept(Socket);函数,这个与其他的事件方法不同,我们来看看它的源码就知道了:

procedure TCustomWinSocket.Accept(Socket: TSocket);

begin

end;

Socket的父类将这个方法设为虚方法,并什么事也不做,可知它的子类ServerWinSocket一定覆盖了这个方法,并可能要做一些线程分配方面的工作,但这又是一个大函数了,又要花一大篇来分析了,但离胜利之地已经不远了,这一步完成,其他就全部都是小菜一碟了。

(41)

procedure TServerWinSocket.Accept(Socket: TSocket);

var

  ClientSocket: TServerClientWinSocket;

  ClientWinSocket: TSocket;

  Addr: TSockAddrIn;

上一页  [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……
    咸宁网络警察报警平台