Delphi Socket 阻塞线程下为什么不触发OnRead和OnWrite事件
//**********************************************************************************
//说明: 阻塞线程下为什么不触发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事件的更多相关文章
- delphi TServerSocket阻塞线程单元 实例
TServerSocket阻塞线程单元,希望对你有所帮助.需要注意的是:1.如果你使用TServerSocket的stNonBlocking模式,重写TServerClientThread线程时要重载 ...
- socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto
socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...
- 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值---部分内容可能不确切,待讨论
1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回值 ...
- 关于socket阻塞与非阻塞情况下的recv、send、read、write返回值(转载)
1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回值 ...
- UNIX网络编程——关于socket阻塞与非阻塞情况下的recv、send、read、write返回值
1.阻塞模式与非阻塞模式下recv的返回值各代表什么意思?有没有 区别?(就我目前了解阻塞与非阻塞recv返回值没有区分,都是 <0:出错,=0:连接关闭,>0接收到数据大小,特别:返回 ...
- Delphi Socket通信及多线程编程总结
http://cxhblog.blog.sohu.com/41930676.html 一.Socket通信: Delphi在ScktComp单元中对WinSock进行了封装,该单元提供了TAbstra ...
- socket阻塞与非阻塞,同步与异步、I/O模型,select与poll、epoll比较
1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端: 同步: 所谓同步,就 ...
- socket阻塞与非阻塞,同步与异步
socket阻塞与非阻塞,同步与异步 作者:huangguisu 转自:http://blog.csdn.net/hguisu/article/details/7453390 1. 概念理解 在进行网 ...
- C#中的线程(下)-多线程
1. 单元模式和Windows Forms 单元模式线程是一个自动线程安全机制, 非常贴近于COM——Microsoft的遗留下的组件对象模型.尽管.NET最大地放弃摆脱了遗留下的模型,但很多时候它 ...
随机推荐
- Iaas-cloudstack
http://cloudstack.apt-get.eu/systemvm/4.6/ 模板地址 http://cloudstack.apt-get.eu/centos7/4.6/ 代理及管理地址 ht ...
- TKinter之窗口美化 窗口大小、图标等
设置窗口大小.设置窗口标题.设置窗口图标 效果图: 代码示例: #!/usr/bin/env python # _*_ coding:utf-8 _*_ from Tkinter import * r ...
- VS 2010 编译安装 boost 库 -(和 jsoncpp 库共存)
boost库的简单应用很容易,网上有很多资料,但是,如果要json 和 boost 一起使用就会出现这样那样的问题, 有时候提示找不到 “libboost_coroutine-vc100-mt-sgd ...
- ant导入Zookeeper到Eclipse错误path contains invalid character
首先在Zookeeper源码目录执行 ant eclipse 遇到错误 path contains invalid character 可以修改\zookeeper\build.xml 文件加入 &l ...
- Spring security与shiro
shiro更轻量级,spring security过于复杂. Apache Shiro 使用手册(一)Shiro架构介绍 Spring Security笔记:Remember Me(下次自动登录)
- Innodb锁机制:Next-Key Lock 浅谈(转)
http://www.cnblogs.com/zhoujinyi/p/3435982.html 数据库使用锁是为了支持更好的并发,提供数据的完整性和一致性.InnoDB是一个支持行锁的存储引擎,锁的类 ...
- openoffice下中文乱码问题解决
在系统安装完OpenOffice进行pdf文档转换的时候 文档会出现乱码如下: 这里主要有两个原因: 1.上传的文件的编码是Windows上的默认编码GBK,而linux服务器默认编码是UTF-8,这 ...
- Hive(二):windows hive ODBC 安装
针对Windows 32位和64位的系统对应有多个版本的 Hive ODBC Connector, 在安装的过程中,版本必须完全匹配(即:32位的 connector 只能在32位的系统运行,64位的 ...
- openstack(liberty):部署实验平台(二,简单版本软件安装 part1)
软件安装过程中,考虑到现在是一个实验环境,且也考虑到规模不大,还有,网络压力不会大,出于简单考虑,将各个节点的拓扑结构改了一下,主要体现在网络节点和控制节点并在了一起.在一个服务器上安装! 到目前位置 ...
- HackerRank "Kundu and Tree" !!
Learnt from here: http://www.cnblogs.com/lautsie/p/3798165.html Idea is: we union all pure black edg ...