深入 CSocket 编程之阻塞和非阻塞模式

发表于:2008-10-13来源:作者:点击数: 标签:阻塞CSocket模式
有时,花上几个小时阅读、调试、跟踪优秀的源码程序,能够更快地掌握某些技术关键点和精髓。当然,前提是对这些技术大致上有一个了解。 我通过几个采用 CSocket 类编写并基于 Client/Server (客户端 / 服务端)的网络聊天和传输文件的程序 ( 详见: 源代码
有时,花上几个小时阅读、调试、跟踪优秀的源码程序,能够更快地掌握某些技术关键点和精髓。当然,前提是对这些技术大致上有一个了解。

  我通过几个采用 CSocket 类编写并基于 Client/Server (客户端 / 服务端)的网络聊天和传输文件的程序 ( 详见: 源代码参考 ) ,在调试这些程序的过程中,追踪深入至 CSocket 类核心源码 Sockcore.cpp , 对于CSocket 类的运行机制可谓是一览无遗,并且对于阻塞和非阻塞方式下的 socket 程序的编写也是稍有体会。

阅读本文请先注意:

  这里的阻塞和非阻塞的概念仅适用于 Server 端 socket 程序。socket 意为套接字,它与 Socket 不同,请注意首字母的大小写。

  客户端与服务端的通信简单来讲:服务端 socket 负责监听,应答,接收和发送消息,而客户端 socket 只是连接,应答,接收,发送消息。此外,如果你对于采用 CSocket 类编写 Client/Server 网络程序的原理不是很了解,请先查询一下( 详见:参考书籍和在线帮助 )。
在此之前,有必要先讲述一下: 网络传输服务提供者, ws2_32.dll , socket 事件 和 socket window 。

1、网络传输服务提供者(网络传输服务进程), Socket 事件, Socket Window

  网络传输服务提供者 ( transport service provider )是以 DLL 的形式存在的,在 windows 操作系统启动时由服务进程 svchost.exe 加载。当 socket 被创建时,调用 API 函数 Socket (在 ws2_32.dll 中), Socket 函数会传递三个参数 : 地址族,套接字类型 ( 注 2 ) 和协议,这三个参数决定了是由哪一个类型的 网络传输服务提供者 来启动网络传输服务功能。所有的网络通信正是由网络传输服务提供者完成 , 这里将 网络传输服务提供者 称为 网络传输服务进程 更有助于理解,因为前文已提到 网络传输服务提供者 是由 svchost.exe 服务进程所加载的。
  下图描述了网络应用程序、 CSocket ( WSock32.dll )、 Socket API(ws2_32.dll) 和 网络传输服务进程 之间的接口层次关系:

  当 Client 端 socket 与 Server 端 socket 相互通信时,两端均会触发 socket 事件。这里仅简要说明两个 socket 事件:

  FD_CONNECT: 连接事件 , 通常 Client 端 socket 调用 socket API 函数 Connect 时所触发,这个事件发生在 Client 端。

  FD_ACCEPT :正在引入的连接事件,通常 Server 端 socket 正在接收来自 Client 端 socket 连接时触发,这个事件发生在 Server 端。

  网络传输服务进程 将 socket 事件 保存至 socket 的事件队列中。此外, 网络传输服务进程 还会向 socket window 发送消息 WM_SOCKET_NOTIFY , 通知有 socket 事件 产生,见下文对 socket window 的详细说明。

  

原文转自:http://www.ltesting.net