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

ServerSocket,ClientSocket控件源码阅读笔记

作者:闵涛 文章来源:闵涛的学习笔记 点击数:7765 更新时间:2009/4/23 18:28:00
>)

procedure Startup;

var

  ErrorCode: Integer;

begin

  ErrorCode := WSAStartup($0101, WSAData);

  if ErrorCode <> 0 then

    raise ESocketError.CreateResFmt(@sWindowsSocketError,

      [SysErrorMessage(ErrorCode), ErrorCode, ''''WSAStartup'''']);

end;

这是一个全局函数,看到其中一行重要的代码了,

ErrorCode := WSAStartup($0101, WSAData);WinSock就是在这里被初始化的。

而在服务端没有建立监听之时,Socket就在上面被默认设置了。

好,现在ServerSocket的成员FserverSocket的创建就完成了,再回到最上面,

FServerSocket := TServerWinSocket.Create(INVALID_SOCKET);之后,便是

InitSocket(FServerSocket);了,看看它的代码:

(12

procedure TAbstractSocket.InitSocket(Socket: TCustomWinSocket);

begin

  Socket.OnSocketEvent := DoEvent;

  Socket.OnErrorEvent := DoError;

end;

正好和上面所说的一样,现在可以认为当Socket发生了事件(比如连接,接收等)之后,就是调用了DoEvent了,错误发生了也一样。不妨看看DoEvent代码:

(121

procedure TAbstractSocket.DoEvent(Sender: TObject; Socket: TCustomWinSocket;

  SocketEvent: TSocketEvent);

begin

  Event(Socket, SocketEvent);

end;

里面是调用Event,再看看Event的声明:

procedure Event(Socket: TCustomWinSocket; SocketEvent: TSocketEvent);virtual; abstract;

这是一个抽象函数,由此可以知道,TAbstractSocket是一个抽象的类,它只是封装了一般的操作,具体地都留到了它的子类中去了,所以它的子类一定覆盖了这个Event方法,而DoEvent中调用的Event实际上就是调用它子类的Event方法,这个就是典型的模板模式。

好,看看它的子类有没有覆盖这个方法,果然在TCustomSocket中看到了这个方法,并实现了它,看看它的源代码:

(1211

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

begin

  case SocketEvent of

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

    seConnecting: if Assigned(FOnConnecting) then FOnConnecting(Self, Socket);

    seConnect:

      begin

        FActive := True;

        if Assigned(FOnConnect) then FOnConnect(Self, Socket);

      end;

    seListen:

      begin

        FActive := True;

        if Assigned(FOnListen) then FOnListen(Self, Socket);

      end;

    seDisconnect:

      begin

        FActive := False;

        if Assigned(FOnDisconnect) then FOnDisconnect(Self, Socket);

      end;

    seAccept: if Assigned(FOnAccept) then FOnAccept(Self, Socket);

    seRead: if Assigned(FOnRead) then FOnRead(Self, Socket);

    seWrite: if Assigned(FOnWrite) then FOnWrite(Self, Socket);

  end;

end;

其中FonAccept等这些都是TCusotmSocket的成员,都是TSocketNotifyEvent类型的,TCustomSocket还通过下面这些属性,使该类拥有了这些事件处理的能力:

property OnLookup: TSocketNotifyEvent read FOnLookup write FOnLookup;

    property OnConnecting: TSocketNotifyEvent read FOnConnecting write FOnConnecting;

    property OnConnect: TSocketNotifyEvent read FOnConnect write FOnConnect;

    property OnDisconnect: TSocketNotifyEvent read FOnDisconnect write FOnDisconnect;

    property OnListen: TSocketNotifyEvent read FOnListen write FOnListen;

    property OnAccept: TSocketNotifyEvent read FOnAccept write FOnAccept;

    property OnRead: TSocketNotifyEvent read FOnRead write FOnRead;

property OnWrite: TSocketNotifyEvent read FOnWrite write FOnWrite;

而上面的Event实现,我们可以看到它是根据SocketEvent的类型来调用相应的事件指针的,而它的子类ServerSocket和ClientSocket也拥有了这些事件的处理能力,到这里我们终于明白了,它们的事件是怎么样出来的,但如果想得知这些事件是怎么触发的,还要看这一句:Socket.OnSocketEvent,OnSocketEvent到后面再说,这里先略。

错误处理事件原理上也是一样,到后面再说。

 

好了,到这里第一步解读完毕,我们所知道的ServerSocket创建之后所完成事件就是初始化Socket DLL,并指定好事件处理的方法指针和错误处理的方法指针。我们接下来看第二步。

 

 

2.我们创建完ServerSocket后,下步要做什么呢,当然是指定端口啦,然后Open开始监视啦,这个过程会触发一些事件,我们正好看看这些事件是怎么样发生的。

由于这一次操作是非阻塞方式的,所以ServerType默认为stNonBlocking,我们开始设置Port,这个属性的声明在哪里,这个属性一直到跟踪祖先类AbstractSocket中去,因为无论客户端和服务端都是要设置端口的,所以理所当然要封装到最高层的类去了,以让它的子类拥有这些属性:

property Port: Integer read FPort write SetPort;

再看看SetPort方法:

(21

procedure TAbstractSocket.SetPort(Value: Integer);

begin

  if FPort <> Value then

  begin

    if not (csLoading in ComponentState) and FActive then

      raise ESocketError.CreateRes(@sCantChangeWhileActive);

    FPort := Value;

  end;

end;

if not (csLoading in ComponentState) and FActive then

      raise ESocketError.CreateRes(@sCantChangeWhileActive);

这一句是防止你在运行时改变端口,最后才将值赋给FPort。

好了,设置后Port后,就要Open了,开始监视客户端了。

监视有两个方式,一种是直接设

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