//**********************************************************************************
//说明: 阻塞线程下为什么不触发OnRead和OnWrite事件
//作者: licwing          时间: 2001-5-18
//Email: rurality@21cn.com
//**********************************************************************************
1.首先先分析TServerSocket的继承关系
  TAbstractSocket->TCustomSocket->TCustomServerSocket->TServerSocket
属性 ServerType 是在 TCustomServerSocket 里面定义的
  property ServerType: TServerType read GetServerType write SetServerType;
同时在TCustomServerSocket里定义了TServerWinSocket,用来处理客户连接
TServerWinSocket的继承关系如下:
  TCustomWinSocket->TServerWinSocket
也就是说我们在TServerSocket里面触发的OnRead,OnWrite事件事实上是由TServerSocket
的父类TCustomServerSocket中的TServerWinSocket触发的。

2.现在我们分析在TCustomServerSocket里定义的TServerWinSocket客户连接方法
procedure TServerWinSocket.Accept(Socket: TSocket);
var
  ClientSocket: TServerClientWinSocket;
  ClientWinSocket: TSocket;
  Addr: TSockAddrIn;
  Len: Integer;
  OldOpenType, NewOpenType: Integer;
begin
  Len := SizeOf(OldOpenType);
  if getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, PChar(@OldOpenType),
    Len) = 0 then
  //从这里开始是处理多线程的
  try
    if FServerType = stThreadBlocking then
    begin
      //  SO_SYNCHRONOUS_NONALERT = $20 在winsock单元里面定义 
      //{$EXTERNALSYM SO_SYNCHRONOUS_NONALERT}
      NewOpenType := SO_SYNCHRONOUS_NONALERT;  
      setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, PChar(@NewOpenType), Len);
    end;
    Len := SizeOf(Addr);
    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
        //********多线程事件响应关键部分*******
//TAsyncStyle = (asRead, asWrite, asOOB, asAccept, asConnect, asClose);
//asRead The socket receives notification that the connection is ready for reading.
        //asWrite The socket receives notification that the connection is ready for writing.
        ClientSocket.ASyncStyles := [];
//*************************************
        GetServerThread(ClientSocket);
      end;
    end;
  finally
    Len := SizeOf(OldOpenType);
    setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, PChar(@OldOpenType), Len);
  end;
end;

3.ASyncStyles属性只有在TCustomWinSocke类里面定义的,再看SetAsyncStyles过程
procedure TCustomWinSocket.DoSetAsyncStyles;
var
  Msg: Integer;
  Wnd: HWnd;
  Blocking: Longint;
begin
  Msg := 0;
  Wnd := 0;
  if FAsyncStyles <> [] then  //非阻塞模式
  begin
    Msg := CM_SOCKETMESSAGE;  //由消息CM_SOCKETMESSAGE触发的过程是过程
                              //TCustomWinSocket.CMSocketMessage(var Message: TCMSocketMessage);
    Wnd := Handle;
  end;
  WSAAsyncSelect(FSocket, Wnd, Msg, Longint(Byte(FAsyncStyles))); //非阻塞模式处理
  if FASyncStyles = [] then   //阻塞模式
  begin
    Blocking := 0;
    ioctlsocket(FSocket, FIONBIO, Blocking);//阻塞模式处理
  end;
end;

4.再看由消息CM_SOCKETMESSAGE触发的过程
procedure TCustomWinSocket.CMSocketMessage(var Message: TCMSocketMessage);
begin
  with Message do
    if CheckError then
      case SelectEvent of
        FD_CONNECT: Connect(Socket);
        FD_CLOSE: Disconnect(Socket);
        FD_READ: Read(Socket);              //触发Read事件
        FD_WRITE: Write(Socket);            //触发Write事件
        FD_ACCEPT: Accept(Socket);
      end;
end;

现在应该明白为什么在阻塞模式下不触发OnRead和OnWrite事件了吧?

Delphi Socket 阻塞线程下为什么不触发OnRead和OnWrite事件的更多相关文章

  1. delphi TServerSocket阻塞线程单元 实例

    TServerSocket阻塞线程单元,希望对你有所帮助.需要注意的是:1.如果你使用TServerSocket的stNonBlocking模式,重写TServerClientThread线程时要重载 ...

  2. socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto

    socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...

  3. 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值---部分内容可能不确切,待讨论

    1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回值  ...

  4. 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值(转载)

    1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回值  ...

  5. UNIX网络编程——关于socket阻塞与非阻塞情况下的recv、send、read、write返回值

    1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有 区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回 ...

  6. Delphi Socket通信及多线程编程总结

    http://cxhblog.blog.sohu.com/41930676.html 一.Socket通信: Delphi在ScktComp单元中对WinSock进行了封装,该单元提供了TAbstra ...

  7. socket阻塞与非阻塞,同步与异步、I/O模型,select与poll、epoll比较

    1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端: 同步:      所谓同步,就 ...

  8. socket阻塞与非阻塞,同步与异步

    socket阻塞与非阻塞,同步与异步 作者:huangguisu 转自:http://blog.csdn.net/hguisu/article/details/7453390 1. 概念理解 在进行网 ...

  9. C#中的线程(下)-多线程

    1.  单元模式和Windows Forms 单元模式线程是一个自动线程安全机制, 非常贴近于COM——Microsoft的遗留下的组件对象模型.尽管.NET最大地放弃摆脱了遗留下的模型,但很多时候它 ...

随机推荐

  1. shell之eval-command

    本文将会讲解一些linux中命令的使用与技巧希望对新手给予帮助一 e v a l命令将会首先扫描命令行进行所有的置换,然后再执行该命令.该命令适用于那些一次扫描无法实现其功能的变量.该命令对变量进行两 ...

  2. Q4: Two Sum

    问题描述: Given an array of integers, find two numbers such that they add up to a specific target number ...

  3. android数据存储之File

    android中使用File进行存储主要使用到OpenFileOutput和OpenFileInput两个方法,下面直接用一个例子来说明一下. (1)布局文件main.xml文件 <?xml v ...

  4. VBA 按照文件类型名称打开一个文件

    Application.GetOpenFilename(fileFilter, fileIndex, fileSelectTitle, button, False) fileFilter: 指定能够被 ...

  5. HTML5 CANVAS 高级

    加载图片 获取图像有三种方式: a : createImageData(),没有效率,一个像素一个像素的绘制: b : var img= document.getElementById("i ...

  6. jQuery checkbox相关

     搬家来的~~~ $('#checkbox').attr('checked'); 返回的是checked或者是undefined解决办法 分类: Jquery2014-03-18 17:10 5523 ...

  7. js 标签云效果

    下载:http://files.cnblogs.com/zjfree/js_tag_list.rar 效果如下: 源码如下: <html> <head> <meta ht ...

  8. 【Hadoop需要的Jar包】Hadoop编程-pom.xml文件

    JDK版本的要求 Hadoop 2.7 以及之后的版本,需要JDK 7: Hadoop 2.6 以及之前的版本,支持JDK 6: 对于Hadoop1.x.x版本,只需要引入1个jar: hadoop- ...

  9. html body标签的几个属性 禁用鼠标右键,禁用鼠标选中文字等

    <body oncontextmenu='return false' ondragstart='return false' onselectstart ='return false' onsel ...

  10. FastReport使用总结三——条码简介

    FastReport Desinger中支持的Barcode类型如下图所示: 设置其Barcode属性可以实现支持不同的条码类型. 注意: 支持的条码类型说明如下: 总结: 1.通过设置Barcode ...