TserverSocket 分析3

2/ stNonBlocking

介绍stNonBlocking之前,要先介绍TserverClientWinSocket

TServerClientWinSocket.Create

  inherited Create(Socket);

  if FServerWinSocket.ASyncStyles <> [] then DoSetAsyncStyles;

 

TserverClientWinSocket 是从TcustomWinSocket继承下来的

  FASyncStyles := [asRead, asWrite, asConnect, asClose];

 

接下来看TCustomWinSocket.DoSetAsyncStyles

  if FAsyncStyles <> [] then

  begin

    Msg := CM_SOCKETMESSAGE;

    Wnd := Handle;

  end;

  WSAAsyncSelect(FSocket, Wnd, Msg, Longint(Byte(FAsyncStyles)));

使用了WSAAsyncSelect 用一个窗口来接受CM_SOCKETMESSAGE 消息来标示网络消息,消息类型 TCustomWinSocket.Create中设置为 FASyncStyles := [asRead, asWrite, asConnect, asClose];asRead, asWrite, asConnect, asClose就是接受的网络消息类型。

 

TCustomWinSocket.CMSocketMessage函数来出来消息CM_SOCKETMESSAGE

  with Message do

    if CheckError then

      case SelectEvent of

        FD_CONNECT: Connect(Socket);

        FD_CLOSE: Disconnect(Socket);

        FD_READ: Read(Socket);

        FD_WRITE: Write(Socket);

        FD_ACCEPT: Accept(Socket);

      end;

根据网络类型调用不同的函数

 

现在开始stNonBlocking类型的研究

TServerWinSocket.Listen

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

调用的父类的Listen

TCustomWinSocket.Listen

  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)

初始化socket ,然后调用了AsyncInitSocket

AsyncInitSocket就是用递归的来实现了端口,地址的解析,最后调用DoListen

TCustomWinSocket.DoListen

  CheckSocketResult(bind(FSocket, FAddr, SizeOf(FAddr)), 'bind');

  DoSetASyncStyles;

  if QueueSize > SOMAXCONN then QueueSize := SOMAXCONN;

  Event(Self, seListen);

  CheckSocketResult(Winsock.listen(FSocket, QueueSize), 'listen');

  FLookupState := lsIdle;

  FConnected := True;

绑定端口,监听,

DoSetASyncStyles中用WSAAsyncSelect实现用窗口接受网络事件消息,不过事件类型在

 TServerWinSocket.Create中初始化为asAccept , FAsyncStyles := [asAccept];

TserverWinSocket重载了Accept函数TServerWinSocket.Accept

    ClientWinSocket := WinSock.accept(Socket, @Addr, @Len);

    if ClientWinSocket <> INVALID_SOCKET then

    begin

      ClientSocket := GetClientSocket(ClientWinSocket);

      if Assigned(FOnSocketEvent) then

        FOnSocketEvent(Self, ClientSocket, seAccept);

接受socket,把socket转换为TserverClientWinSocket

TServerWinSocket.GetClientSocket

Result := TServerClientWinSocket.Create(Socket, Self);

产生了一个TserverClientWinSocket对象,按照我们开始研究的时候,TserverClientWinSocket生成一个窗口自动接受socket消息。

 

总结:

TserverWinSocket创建一个窗口只接受accept网络消息,当消息来了后accept客户端的socket,把客户端的socket转换成TserverClientWinSocketTserverClientWinSocket也创建一个窗口接受asRead, asWrite, asConnect, asClose网络消息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值