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最大地放弃摆脱了遗留下的模型,但很多时候它 ...
随机推荐
- MySql远程连接无法打开解决办法
1.改表法. 请使用mysql管理工具,如:SQLyog Enterprise 可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost的那台电脑使用mysql管理工 ...
- 【web】 亿级Web系统搭建——单机到分布式集群
当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题.为了解决这些性能压力带来问题,我们需要在Web系统架 ...
- VBA 按照文件类型名称打开一个文件
Application.GetOpenFilename(fileFilter, fileIndex, fileSelectTitle, button, False) fileFilter: 指定能够被 ...
- C++资料大全
本文内容源自GitHub<Awesome C/C++>. 关于 C++ 框架.库和资源的一些汇总列表,由 fffaraz 发起和维护. 内容包括:标准库.Web应用框架.人工智能.数据库. ...
- 【jmeter】关联-正则表达和xpath
话说LoadRunner有的一些功能,比如:参数化.检查点.集合点.关联,Jmeter也都有这些功能,只是功能可能稍弱一些,今天就关联来讲解一下. JMeter的关联方法有两种:后置处理器-正则表达式 ...
- 【linux】find命令详解
find命令格式:find [搜索范围][匹配条件] -name 参数:按照名字查找 [root@andon ~]# find /root -name test ###精确查找 /root/test ...
- 使用 OWIN 作为 ASP.NET Web API 的宿主
使用 OWIN 作为 ASP.NET Web API 的宿主 ASP.NET Web API 是一种框架,用于轻松构建可以访问多种客户端(包括浏览器和移动 设备)的 HTTP 服务. ASP.NET ...
- java-多态性
1 多态性 主要表现在上转型对象 2 强制类型转换 2.1 基本类型的强制类型转换 转换只能在数值间进行.包括整数型.字符型.浮点型.数值类型和布尔类型间不能转换. 2.2 引用类型变量转换成其子类型 ...
- BOOST的AUTO link机制以及配置
我们在使用BOOST的时候,如果需要链接一些库,是不用我们手动去链接的,归根结底还是boost的auto_link这个机制,在boost下的auto_link.hpp这个文件夹里面,基本可以看出要根据 ...
- python正则表达式的学习记录
match和findall的区别以及有括号和无括号的区别 strvar = "hello\n\nworld" find_re = re.compile("hello[.| ...