TserverSocket 分析1

TserverSocket 分析

Servertype 有两个值stNonBlocking stThreadBlocking

1、  先讨论stThreadBlocking

这种类型的server 从字面意思上看有thread,他一定使用了线程了

TServerWinSocket.Listen

  if FConnected and (ServerType = stThreadBlocking) then

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

Server监听之后就会创建一个接受线程。

 

看看这个线程做了什么

  while not Terminated do

FServerSocket.Accept(FServerSocket.SocketHandle);

很简单的代码,就是不停的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);

      if FServerType = stThreadBlocking then

      begin

        ClientSocket.ASyncStyles := [];

        GetServerThread(ClientSocket);

      end;

end;

接受客户的连接,然后转换socket TserverClientWinSocket类(GetClientSocket的功能),设置style[],调用 GetServerThread(ClientSocket);

 

我们继续TServerWinSocket.GetServerThread

    for I := 0 to FActiveThreads.Count - 1 do

      if TServerClientThread(FActiveThreads[I]).ClientSocket = nil then

      begin

        Result := FActiveThreads[I];

        Result.ReActivate(ClientSocket);

        Break;

      end;

看线程池中有没有空闲的线程。

  if Result = nil then

  begin

    if Assigned(FOnGetThread) then FOnGetThread(Self, ClientSocket, Result);

    if Result = nil then Result := DoCreateThread(ClientSocket);

  end;

没有的就DoCreateThread

TServerWinSocket.DoCreateThread

  Result := TServerClientThread.Create(False, ClientSocket);

产生一个新的线程TserverClientThread

 

这个新的客户端线程在做什么呢TServerClientThread.ClientExecute

  while not Terminated and ClientSocket.Connected do

  begin

    FD_ZERO(FDSet);

    FD_SET(ClientSocket.SocketHandle, FDSet);

    TimeVal.tv_sec := 0;

    TimeVal.tv_usec := 500;

    if (select(0, @FDSet, nil, nil, @TimeVal) > 0) and not Terminated then

      if ClientSocket.ReceiveBuf(FDSet, -1) = 0 then Break

      else Synchronize(DoRead);

    if (select(0, nil, @FDSet, nil, @TimeVal) > 0) and not Terminated then

      Synchronize(DoWrite);

  end;

原来不停的调用select来读写。

 

总结一下

listen的时候生成一个接受线程TserverAcceptThread,线程每接受到一个客户端,生成一个线程TserverClientThread,不停select

那为什么脚threadblock呢,原来在接受到客户端后设置ClientSocket.ASyncStyles := [];

TCustomWinSocket.DoSetAsyncStyles

  if FASyncStyles = [] then

  begin

    Blocking := 0;

    ioctlsocket(FSocket, FIONBIO, Blocking);

  end;

设置为阻塞模式。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Delphi中的TServersocket控件用于在应用程序中创建TCP/IP服务器。它允许应用程序与远程客户端建立连接,并通过这些连接交换数据。 TServersocket控件是通过监听特定的服务端口来等待客户端的连接请求。当有客户端请求连接时,TServersocket会自动创建一个新的线程来处理该连接,以避免主线程阻塞。 在Delphi中,我们可以通过编写OnClientConnect事件处理程序来添加自定义代码,以便在客户端连接时执行特定的操作。例如,我们可以在该事件中显示连接客户端的IP地址或发送“欢迎”消息。 TServersocket还提供了OnClientRead和OnClientWrite事件处理程序,可以在每次读取和写入数据时执行相应的操作。例如,在OnClientRead事件中,我们可以处理接收到的数据,并根据情况发送响应给客户端。 此外,TServersocket还支持多个并发连接。每个连接都会自动分配一个新的线程,以便并行处理多个客户端。这使得我们可以同时与多个客户端进行通信,而无需手动管理线程。 线程的管理是由TServersocket控件自动处理的,因此我们无需过于关注线程的创建和销毁。然而,我们应该确保在线程中正确地处理异常和释放资源,以避免潜在的内存泄漏或应用程序崩溃。 总的来说,Delphi的TServersocket控件提供了一个简单而强大的方式来创建TCP/IP服务器。它使用线程来处理客户端连接,使我们能够高效地管理并发连接,并实现自定义操作,以满足特定的应用程序需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值