winsocket创建的套接字默认都是阻塞的,阻塞的意思其实很简单,就是不到黄河不死心的工作方式,譬如我们现在要从这个socket recv数据,如果这个时候没有数据可读或者不可读,那它就会等在那,recv下面的代码也不会执行,直到有数据可读;
winsocket提供了系统调用,可以设置socket的模式为非阻塞,很简单
unsigned long on=1;
ioctlsocket(m_socket, FIONBIO, &on) ;
这样就把m_socket由默认的阻塞模式修改为非阻塞模式了,非阻塞模式的工作方法就是,不可读或不可写,掉头就走,不会等待到可读可写,recv或send下面的代码都是可以执行的。
winsocket提供的select模式有是什么呢,个人理解是上面两种(阻塞跟非阻塞)不能覆盖到开发人员的所有使用场景,可能有这样一个使用场景,在有限的时间里等待,如果没有那就结束,那就是超时,当然用非阻塞的方式在加上写点代码来控制超时,也是完全可以办到的,select最早是unix内核实现的,winsocket是从unix引进的,
select的工作原理就是,在对socket操作前(读,写),在一定时间范围内(timeout),先让内核检查下这个socket的状态,然后根据内核返回的状态来定后面的操作,如果可操作(指可读或可写),那就执行操作,如果超时,那说明socket不具备操作条件,就别做无用功了
select的定义如下,跟unix的定义是一样的:
int select( int nfds, fd_set FAR * readfds, fd_set FAR * writefds, fd_set FAR *exceptfds, const struct timeval FAR * timeout );
大致说下参数含义:
nfds:检查的文件描述符个数,windows上写0,就行
readfds:检测可读的文件描述符数组,譬如,我要检查m_socket1是否可读,那把m_socket加到这个数组中,通过FD_SET(m_socket,&readfds)就OK了
writefds:检测可写的文件描述符数组,方法同readfds
exceptfds:检测发生异常的文件描述符数组,方法同readfds
timeout :是检测的超时时间
注意:select对于非阻塞模式socket,结果也一样会等timeout的时间,
如果timeout =NULL,会导致blocking,工作方式就跟阻塞socket一样
timeout结构填0,timeout.tv_sec = 0; timeout.tv_usec = 0;那么与非阻塞的socket的效果一样
winsocket异步模型--select模式介绍
最新推荐文章于 2020-11-24 13:15:50 发布