Windows网络编程系列教程之四:Select模型
讲一下套接字模式和套接字I/O模型的区别。先说明一下,只针对Winsock,如果你要骨头里挑鸡蛋把UNIX下的套接字概念来往这里套,那就不关我的事。
套接字模式:阻塞套接字和非阻塞套接字。或者叫同步套接字和异步套接字。
套接字模型:描述如何对套接字的I/O行为进行管理。
Winsock提供的I/O模型一共有五种:
select,WSAAsyncSelect,WSAEventSelect,Overlapped,Completion。今天先讲解select。
1:select模型(选择模型)
先看一下下面的这句代码:
int iResult = recv(s, buffer,1024);
这是用来接收数据的,在默认的阻塞模式下的套接字里,recv会阻塞在那里,直到套接字连接上有数据可读,把数据读到buffer里后recv函数才会返
回,不然就会一直阻塞在那里。在单线程的程序里出现这种情况会导致主线程(单线程程序里只有一个默认的主线程)被阻塞,这样整个程序被锁死在这里,如果永
远没数据发送过来,那么程序就会被永远锁死。这个问题可以用多线程解决,但是在有多个套接字连接的情况下,这不是一个好的选择,扩展性很差。Select
模型就是为了解决这个问题而出现的。
再看代码:
int iResult = ioctlsocket(s, FIOBIO, (unsigned long *)&ul);
iResult = recv(s, buffer,1024);
这一次recv的调用不管套接字连接上有没有数据可以接收都会马上返回。原因就在于我们用ioctlsocket把套接字设置为非阻塞模式了。不过你跟踪
一下就会发现,在没有数据的情况下,recv确实是马上返回了,但是也返回了一个错误:WSAEWOULDBLOCK,意思就是请求的操作没有成功完成。
看到这里很多人可能会说,那么就重复调用recv并检查返回值,直到成功为止,但是这样做效率很成问题,开销太大。
感谢天才的微软工程师吧,他们给我们提供了好的解决办法。
先看看select函数
int select(
int nfds,
fd_set FAR *readfds,
fd_set FAR *writefds,
fd_set FAR *exceptfds,
const struct timeval FAR *timeout
);
第一个参数不要管,会被系统忽略的。第二个参数是用来检查套接字可读性,也就说检查套接字上是否有数据可读,同样,第三个参数用来检查数据是否可以发出。最后一个是检查是否有带外数据可读取。
参数详细的意思请去看MSDN,这里限于篇幅不详细解释了。
最后一个参数是用来设置select等待多久的,是个结构:
struct timeval {
long tv_sec; // seconds
long tv_usec; // and microseconds
};
如果将这个结构设置为(0,0),那么select函数会马上返回。
说了这么久,select的作用到底是什么?
他的作用就是:防止在在阻塞模式的套接字里被锁死,避免在非阻塞套接字里重复检查WSAEWOULDBLOCK错误。
他的工作流程如下:
1:用FD_ZERO宏来初始化我们感兴趣的fd_set,也就是select函数的第二三四个参数。
2:用FD_SET宏来将套接字句柄分配给相应的fd_set。
3:调用select函数。
4:用FD_ISSET对套接字句柄进行检查,如果我们所关注的那个套接字句柄仍然在开始分配的那个fd_set里,那么说明马上可以进行相应的IO操
作。比如一个分配给select第一个参数的套接字句柄在select返回后仍然在select第一个参数的fd_set里,那么说明当前数据已经来了,
马上可以读取成功而不会被阻塞。
下面给出一个简单的select模型的服务端套接字。








































































基本上就这样,个人感觉select模型用处不是很大,我只用过一次,去年写端口扫描器的时候用select来检查超时。
感觉讲得不是很清楚,虽然东西我很明白,但是要讲解出来讲解得很清楚真不容易。
Windows网络编程系列教程之四:Select模型的更多相关文章
- [转载]Windows网络编程系列教程之四:Select模型
原文:http://www.51see.com/asp/bbs/public/bp_show.asp?t_id=200308131152297103 讲一下套接字模式和套接字I/O模型的区别.先说明一 ...
- 网络编程第六讲Select模型
网络模型第六讲Select模型 一丶Select模型是什么 以前我们讲过一个迭代模型.就是只服务一个客户端连接.但是实际网络编程中.复杂的很多. 比如一个 C/S架构程序 (客户端/服务端) 客户端很 ...
- Linux 网络编程系列教程
一.基础理论篇 01.网络协议入门 02.LAN.WAN.WLAN.VLAN 和 VPN 的区别 03.IP 地址介绍 04.广播地址介绍 05.无连接和面向连接协议的区别 06.因特网的IP协议是不 ...
- Socket网络编程系列教程序
C语言的用途相当多,可以用在数据结构.数据库.网络.嵌入式等方面,历经40多年不衰,真是厉害!最近一直想从某一应用方面写一个系列教程,好好地把某一方面讲深讲透. 正好博主对网络方面的编 ...
- TCP/IP网络编程系列之四(初级)
TCP/IP网络编程系列之四-基于TCP的服务端/客户端 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于流的 ...
- Linux 网络编程的5种IO模型:多路复用(select/poll/epoll)
Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 背景 我们在上一讲 Linux 网络编程的5种IO模型:阻塞IO与非阻塞IO中,对于其中的 阻塞/非阻塞IO 进行了 ...
- 猫哥网络编程系列:详解 BAT 面试题
从产品上线前的接口开发和调试,到上线后的 bug 定位.性能优化,网络编程知识贯穿着一个互联网产品的整个生命周期.不论你是前后端的开发岗位,还是 SQA.运维等其他技术岗位,掌握网络编程知识均是岗位的 ...
- 猫哥网络编程系列:HTTP PEM 万能调试法
注:本文内容较长且细节较多,建议先收藏再阅读,原文将在 Github 上维护与更新. 在 HTTP 接口开发与调试过程中,我们经常遇到以下类似的问题: 为什么本地环境接口可以调用成功,但放到手机上就跑 ...
- (转)Windows驱动编程基础教程
版权声明 本书是免费电子书. 作者保留一切权利.但在保证本书完整性(包括版权声明.前言.正文内容.后记.以及作者的信息),并不增删.改变其中任何文字内容的前提下,欢迎任何读者 以任何形式(包括 ...
随机推荐
- rem和em的用法
1.rem转化为向素值的方法 rem单位转化为像素大小取决于根元素的字体大小,即HTML元素的字体大小,根元素字体大小乘以rem. 例:根元素的字体大小 16px,10rem 将等同于 160px,即 ...
- ASP.NET Core学习网站推荐
跟大家推荐一个不错的学习.NET Core 的网站,这个网站的视频是付费的,但是录视频的都是.NET Core的大佬们,个人觉得很不错推荐出来 video.jessetalk.cn
- Spark实际项目中调节并行度
实际项目中调节并行度 实际项目中调节并行度 并行度概述 spark架构一览 如果不调节并行度,导致并行度过低,会怎么样? 设置spark作业并行度 小结 并行度概述 其实就是指的是,Spark作业中, ...
- React 源码中的依赖注入方法
一.前言 依赖注入(Dependency Injection)这个概念的兴起已经有很长时间了,把这个概念融入到框架中达到出神入化境地的,非Spring莫属.然而在前端领域,似乎很少会提到这个概念,难道 ...
- Matlab R2018a版离线使用帮助文档方法
转载自:Matlab R2018a版离线使用帮助文档方法 问题 Matlab R2018a版本安装后,帮助文档默认为在线方式,需要使用账号登录,如果没有激活密钥或许可证编号,就无法使用帮助文档了. 方 ...
- Java设计模式(10)——结构型模式之代理模式(Proxy)
一.概述 概念 UML简图 实际使用的场景示例 如果那个对象是一个是很大的图片,需要花费很长时间才能显示出来,那么当这个图片包含在文档中时,使用编辑器或浏览器打开这个文档,打开文档必须很迅速,不能等待 ...
- 20145234黄斐《信息安全系统设计基础》第六周学习总结(Y86模拟器的安装)
Y86模拟器的安装 由于本人的电脑有些问题,在安装的时候忽然断电导致之前的成果都没有截图. 1.安装bison和flex词法分析工具 sudo apt-get install bison flex t ...
- EL/JSTL-jsp页面更简单的输出方式
1.EL(Expression Language):表达式语言,用于页面输出 格式:${表达式} EL支持四则运算,关系运算[常用eq来比较字符串或判断相等],逻辑运算 EL访问空间内对象,[类.对象 ...
- Codeforces431C_K-Tree_KEY
题目传送门 题目大意:给定一棵K叉树,一个节点下的K个节点的分数为i,求包含大于等于D的边的总分数为N的方案总数,mod 1e9+7. 这是一道很好的树形DP题,首先看N和K两个条件,可以轻易的得到方 ...
- (AOSP)repo checkout指定版本
aosp 怎么切换分支? To properly switch Android version, all you need to change is branch for your manifest ...