Winsock 的I/O操作: 1、 两种I/O模式 * 阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序。套接字 默认为阻塞模式。可以通过多线程技术进行处理。 * 非阻塞模式:执行I/O操作时,Winsock函数会返回并交出控制权。这种模式使用 起来比较复杂,因为函数在没有运行完成就进行返回,会不断地返回 WSAEWOULDBLOCK错误。但功能强大。 为了解决这个问题,提出了进行I/O操作的一些I/O模型,下面介绍最常见的三种:
2、select模型: 通过调用select函数可以确定一个或多个套接字的状态,判断套接字上是否有数据,或者能否向一个套接字写入数据。 int Select( int nfds, fd_set FAR * readfds, fd_set FAR * writefds, fd_set FAR *exceptfds, const struct timeval FAR * timeout ); Select模型是最常见的I/O模型。使用 int select( int nfds , fd_set FAR* readfds , fd_set FAR* writefds,fd_set FAR* exceptfds,const struct timeval FAR * timeout ) ; 函数来检查你要调用的Socket套接字是否已经有了需要处理的数据。 select包含三个Socket队列,分别代表: readfds ,检查可读性,writefds,检查可写性,exceptfds,例外数据。 timeout是select函数的返回时间。例如,我们想要检查一个套接字是否有数据需要接收,我们可以把套接字句柄加入可读性检查队列中,然后调用select,如果,该套接字没有数据需要接收, select函数会把该套接字从可读性检查队列中删除掉,所以我们只要检查该套接字句柄是否还存在于可读性队列中,就可以知道到底有没有数据需要接收了。 WinSock提供了一些宏用来操作套接字队列fd_set。 FD_CLR( s,*set) 从队列set删除句柄s。 FD_ISSET( s, *set) 检查句柄s是否存在与队列set中。 FD_SET( s,*set )把句柄s添加到队列set中。 FD_ZERO( *set ) 把set队列初始化成空队列。 ◆先来看看涉及到的结构的定义: <A> fd_set结构: #define FD_SETSIZE 64? typedef struct fd_set { SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */ fd_count为已设定socket的数量fd_array为socket列表,FD_SETSIZE为最大socket数量,建议不小于64。这是微软建议的。 <B> timeval结构: struct timeval ◆再来看看select函数各参数的作用: 举例:测试一个套接字是否可读: fd_set fdread;//FD_ZERO定义
◆I/O操作函数:主要用于获取与套接字相关的操作参数。 支持下列命令: 兼容性: 本函数为Berkeley套接口函数ioctl()的一个子集。其中没有与FIOASYNC等价的命令,SIOCATMARK是套接口层次支持的唯一命令。 返回值: 成功后,ioctlsocket()返回0。否则的话,返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码。 错误代码: WSANOTINITIALISED:在使用此API之前应首先成功地调用WSAStartup()。 WSAENETDOWN:WINDOWS套接口实现检测到网络子系统失效。 WSAEINVAL:cmd为非法命令,或者argp所指参数不适用于该cmd命令,或者该命令不适用于此种类型的套接口。 WSAEINPROGRESS:一个阻塞的WINDOWS套接口调用正在运行中。 WSAENOTSOCK:描述字不是一个套接口。
|
Select() 与 ioctlsocket()
最新推荐文章于 2023-04-24 08:09:49 发布