TserverSocket 分析1

本文详细解析了TserverSocket在stThreadBlocking模式下的工作原理。通过创建TServerAcceptThread来不断接收新连接,并为每个连接分配独立的TServerClientThread进行处理,实现了高效的并发服务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;

设置为阻塞模式。

 

 

org.apache.thrift.transport.TTransportException: Could not create ServerSocket on address 0.0.0.0/0.0.0.0:9083. at org.apache.thrift.transport.TServerSocket.<init>(TServerSocket.java:109) at org.apache.thrift.transport.TServerSocket.<init>(TServerSocket.java:91) at org.apache.thrift.transport.TServerSocket.<init>(TServerSocket.java:87) at org.apache.hadoop.hive.metastore.utils.SecurityUtils.getServerSocket(SecurityUtils.java:253) at org.apache.hadoop.hive.metastore.HiveMetaStore.startMetaStore(HiveMetaStore.java:8979) at org.apache.hadoop.hive.metastore.HiveMetaStore.main(HiveMetaStore.java:8854) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.hadoop.util.RunJar.run(RunJar.java:323) at org.apache.hadoop.util.RunJar.main(RunJar.java:236) Caused by: java.net.BindException: Address already in use (Bind failed) at java.net.PlainSocketImpl.socketBind(Native Method) at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:513) at java.net.ServerSocket.bind(ServerSocket.java:375) at org.apache.thrift.transport.TServerSocket.<init>(TServerSocket.java:106) ... 11 more Exception in thread "main" org.apache.thrift.transport.TTransportException: Could not create ServerSocket on address 0.0.0.0/0.0.0.0:9083. at org.apache.thrift.transport.TServerSocket.<init>(TServerSocket.java:109) at org.apache.thrift.transport.TServerSocket.<init>(TServerSocket.java:91) at org.apache.thrift.transport.TServerSocket.<init>(TServerSocket.java:87) at org.apache.hadoop.hive.metastore.utils.SecurityUtils.getServerSocket(SecurityUtils.java:253) at org.apache.hadoop.hi
最新发布
04-02
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值