Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如
connect、accept、recv或recvfrom这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等
待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回)。可是使用Select就可以完成非阻塞(所谓非阻塞方式non-
block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相
同,若事件没有发生则返回一个代码来告知事件未发生,而进程或线程继续执行,所以效率较高)方式工作的程序,它能够监视我们需要监视的文件描述符的变化情
况——读写或是异常。下面详细介绍一下!
Select的函数格式(我所说的是Unix系统下的伯克利socket编程,和windows下的有区别,一会儿说明):
int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);
先说明两个结构体:
第
一,struct fd_set可以理解为一个集合,这个集合中存放的是文件描述符(file
descriptor),即文件句柄,这可以是我们所说的普通意义的文件,当然Unix下任何设备、管道、FIFO等都是文件形式,全部包括在内,所以毫
无疑问一个socket就是一个文件,socket句柄就是一个文件描述符。fd_set集合可以通过一些宏由人为来操作,比如清空集合FD_ZERO
(fd_set *),将一个给定的文件描述符加入集合之中FD_SET(int ,fd_set
*),将一个给定的文件描述符从集合中删除FD_CLR(int
,fd_set*),检查集合中指定的文件描述符是否可以读写FD_ISSET(int ,fd_set* )。一会儿举例说明。
第二,struct timeval是一个大家常用的结构,用来代表时间值,有两个成员,一个是秒数,另一个是毫秒数。
具体解释select的参数:
int maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!在Windows中这个参数的值无所谓,可以设置不正确。
fd_set
*readfds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的读变化的,即我们关心是否可以从这些文件中
读取数据了,如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读,如果没有可读的文件,则根据timeout参数再判断
是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的读变化。
fd_set
*writefds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的写变化的,即我们关心是否可以向这些文件
中写入数据了,如果这个集合中有一个文件可写,select就会返回一个大于0的值,表示有文件可写,如果没有可写的文件,则根据timeout参数再判
断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值。可以传入NULL值,表示不关心任何文件的写变化。
fd_set *errorfds同上面两个参数的意图,用来监视文件错误异常。
struct
timeval*
timeout是select的超时时间,这个参数至关重要,它可以使select处于三种状态,第一,若将NULL以形参传入,即不传入时间结构,就是
将select置于阻塞状态,一定等到监视文件描述符集合中某个文件描述符发生变化为止;第二,若将时间值设为0秒0毫秒,就变成一个纯粹的非阻塞函数,
不管文件描述符是否有变化,都立刻返回继续执行,文件无变化返回0,有变化返回一个正值;第三,timeout的值大于0,这就是等待的超时时间,即
select在timeout时间内阻塞,超时时间之内有事件到来就返回了,否则在超时后不管怎样一定返回,返回值同上述。
返回值:
负值:select错误 正值:某些文件可读写或出错 0:等待超时,没有可读写或错误的文件
在有了select后可以写出像样的网络程序来!举个简单的例子,就是从网络上接受数据写入一个文件中。
例子:
main()
{
int sock;
FILE *fp;
struct fd_set fds;
struct timeval timeout={3,0}; //select等待3秒,3秒轮询,要非阻塞就置0
char buffer[256]={0}; //256字节的接收缓冲区
/* 假定已经建立UDP连接,具体过程不写,简单,当然TCP也同理,主机ip和port都已经给定,要写的文件已经打开
sock=socket(...);
bind(...);
fp=fopen(...); */
while(1)
{
FD_ZERO(&fds); //每次循环都要清空集合,否则不能检测描述符变化
FD_SET(sock,&fds); //添加描述符
FD_SET(fp,&fds); //同上
maxfdp=sock>fp?sock+1:fp+1; //描述符最大值加1
switch(select(maxfdp,&fds,&fds,NULL,&timeout)) //select使用
{
case -1: exit(-1);break; //select错误,退出程序
case 0:break; //再次轮询
default:
if(FD_ISSET(sock,&fds)) //测试sock是否可读,即是否网络上有数据
{
recvfrom(sock,buffer,256,.....);//接受网络数据
if(FD_ISSET(fp,&fds)) //测试文件是否可写
fwrite(fp,buffer...);//写入文件
buffer清空;
}// end if break;
}// end switch
}//end while
}//end main
分享到:
相关推荐
Socket编程是网络编程的基础,它提供了进程间通信的能力,特别是在分布式系统中,使得不同计算机上的程序可以相互通信。在本主题中,我们将深入探讨如何使用`select`机制和线程池来构建高效的TCP、UDP服务器,以及...
代码主要是socket编程的select模式的实现,多并发的基础,可以同时处理多个连接
本篇将重点讲解易语言中的Socket编程,特别是Select模型的应用。 Socket,通常被称为套接字,是网络通信的基础接口,它允许程序通过网络发送和接收数据。在易语言中,Socket编程可以用来实现客户端与服务器之间的...
本文将深入探讨如何使用C++在Windows环境下实现Socket编程中的Select I/O模型。Select模型是一种经典的多路复用I/O机制,它允许单个进程同时监控多个文件描述符(包括套接字)的状态,以检测何时可以进行读写操作。 ...
本压缩包文件"易语言Socket编程之Select模型源码.rar"提供了关于易语言中使用Select模型进行Socket编程的源代码示例。 Select模型是多路复用I/O的一种方式,广泛应用于网络编程中,特别是在处理大量并发连接时。它...
总之,易语言Socket编程中的Select模型是实现高并发网络服务的关键技术,通过合理地使用,开发者可以构建出稳定且性能优良的网络应用。学习并理解这个模型,对于提升易语言网络编程能力大有裨益。
资源为压缩包, 有一DOC文档,并附有源码 程式演示了使用SELECT模式进行多用户连接数据接收处理。...SELECT 原理为监测每个SOCKET的连接ID的状态变化,当有变化时(有数据到来),使用它进行接收
综上所述,`select`方式的并发服务器模型在Linux下的Socket编程中具有重要的应用价值,它允许服务器高效地处理多个并发连接,是构建网络服务的基础之一。通过分析`tcpserver.c`和`tcpclient.c`的源代码,我们可以...
这个`Socket编程之Select模型.rar`压缩包包含了关于如何使用`select`函数进行Socket编程的易语言源码,这对于理解`select`模型的工作原理以及在实际编程中应用非常有帮助。 首先,我们需要理解`select`函数的基本...
总结,Socket编程中的`select`模型是实现高效并发处理的关键,它允许服务器在一个线程中监控多个Socket,降低了系统资源的消耗。同时,通过结合线程机制,可以在保证响应速度的同时,有效地管理大量的并发连接。通过...
在socket编程中,recv()函数经常被用到,当select()检测到网络套接字上有数据可读时,就可以调用recv()来读取数据。 总之,select模型是I/O多路复用技术的基础,它通过监视多个文件描述符来提高程序的效率。尽管...
C语言SOCKET编程指南 本文档提供了C语言SOCKET...23. select()函数:select()函数是SOCKET编程中的一个重要函数,用于多路同步I/O。 24. 参考资料:本文档提供了许多参考资料,用于深入学习SOCKET编程的相关知识点。
在IT领域,网络编程是不可或缺的一部分,而Socket编程则是实现客户端和服务器...通过对`server.cpp`和`client.cpp`代码的学习,我们可以深入理解socket编程和`select`模型的工作原理,为后续的网络编程打下坚实基础。
- select/poll/epoll:讲解I/O复用技术,提高Socket编程的效率。 - SSL/TLS安全通信:介绍如何使用Socket实现加密的网络传输。 7. 实战案例: - 基本的客户端-服务器程序:编写简单的TCP或UDP通信示例。 - 复杂...
在计算机网络编程中,Socket接口是实现进程间通信(IPC)的一种重要方式,特别是在跨网络的通信中。而在Windows系统下,Win32 Socket API(通常称为Winsock)为开发者提供了丰富的功能来构建网络应用。本文将重点...
Socket编程是网络编程的核心部分,而`select`函数在多路复用IO模型中扮演着重要角色,尤其在处理大量并发连接时。本篇文章将深入探讨`select`模式在Socket编程中的应用及其工作原理。 首先,`select`是一个系统调用...
它可以通过IP地址和端口号的构造函数创建,具有`Address`、`AddressFamily`、`Port`等属性,方便我们在Socket编程中使用。 DNS(Domain Name System)是网络中的名称解析服务,`Dns`类提供了查询DNS信息的方法。...