请问WinSock SDK里面的select函数怎么用啊

chchch 2003-08-18 07:53:12
我现在必须用阻塞方式来Read和Accept,可是阻塞方式就停到那里,我的线程无法从内部关闭,我想请教select怎么用的,怎么能不停到那里
...全文
94 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
chchch 2003-08-22
  • 打赏
  • 举报
回复
唉呀,没有给smch(Ashes Of Time)分,我第一次来这个论坛,不会用这些
对不起啊,不好意思
chchch 2003-08-22
  • 打赏
  • 举报
回复
非常感谢nicolas2001(nick),我可以关闭贴子了
smch 2003-08-21
  • 打赏
  • 举报
回复
谢谢两位啊
有个问题啊,比如Accept和Recv,阻塞方式下,程序就会停到那里啊,那我怎么在线程内部关闭线程能.就算是设置了全局变量,也没有办法啊
还有就是那位高手能告诉我select怎么用啊,WSAASyncSelect我知道的,select的那几个参数我没看明白,也不知道select的作用是什么
另外,怎样在Accept和Recv之前能得到端口的状态呢?比如是否有connect请求或者数据要求接受的,然后我在调用相应函数接受,避免卡死
问题加分到60
--------------------------------------------------------------------
对于阻塞模式是无法在线程本身来关闭的(不能向下运行还怎么关闭?),必须由其它线程连接一下然后通过我说的方法。设置一个全局变量,判断是否继续向下走。
要象你说的,避免卡死只能用异步,同步必须要accept,否则客户端就无法connect。而一旦accept就阻塞。
nicolas2001 2003-08-21
  • 打赏
  • 举报
回复
select()* 执行同步I/O多路复用。
select函数的参数( int nfds, fd_set readfds,
fd_set writefds, fd_set exceptfds, const struct timeval timeout )
我记得是:第一个是个较为次要的值,设成0就行了。
后面的几个FD_SET类型的参数才是最重要的;
第一个FD_SET型的参数readfds是表示要被检查是否可读的 Sockets,把你想要接收数据的那个套接字放在这里;
第二个FD_SET参数ritefds是表示要被检查是否可写的 Sockets,将你要发送数据的套接字放在这里;
还有个FD_SET参数exceptfds是表示要被检查是否有错误的 Sockets
select() 函式的第五个参数timeout,是让我们用来设定 select 函数要等
待(block)多久。兹述说如下:

(1)如果 timeout 设为「NULL」,那么 select() 就会一直等到「至少」某
一个 socket 的事件成立了才会 return,这和其他的 blocking 函数一样。

select( ..., NULL ) /* blocking */

(2)如果 timeout 的值设为 {0, 0} (秒, 微秒),那么 select() 在检查后,
不管有没有 socket 的事件成立,都会马上 return,而不会停留。

timeout.tv_sec = timeout.tv_usec = 0;
select( ..., &timeout ) /* non-blocking */

(3)如果 timout 设为 {m, n},那么就会等到至少某一个 socket 的事件发
生,或是时间到了(m 秒 n 微秒),才会 return。

timeout.tv_sec = m;
timeout.tv_usec = n;
select( ..., &timeout ) /* wait m secconds n microseconds */

返回值: 成功 - 符合条件的 Sockets 总数 (若 Timeout 发生,则为 0)
失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)

说明: 使用者可利用此函式来检查 Sockets 是否有资料可被读取,
或是有空间可以写入,或是有错误发生。

关于对FD_SET类型的操作,有几个比较重要的宏:
FD_ZERO(*set) -- 将 set 的值清乾净
FD_SET(s, *set) -- 将 s 加到 set 中
FD_CLR(s, *set) -- 将 s 从 set 中删除
FD_ISSET(s, *set) -- 检查 s 是否存在於 set 中

参数 readfds、writefds、及 exceptfds 都是 「called by value-
result」;而「called by value-result」的意思就是说,我们在将参数传给系统
时,要先设启始值,并将这些参数的位址(address)告诉系统;而系统则会利
用到这些值来做些运算或其他用途,最后并将结果再写回这些参数的位址中。
因此这些参数的值在传入前和函数返回后,可能会不同;所以每次调用
select() 前,对这些参数一定要重新设定它们的值。

假设我们要检查 socket 1 和 2 目前是否可以用来传送资料,以及 socket 3 是
否有资料可读;我们不打算检查 sockets 是否有错误发生,所以 exceptfds 设为
NULL。步骤大致如下:

FD_ZERO( &writefds ); /* 清除 writefds */
FD_ZERO( &readfds ); /* 清除 readfds */
FD_SET( 1, &writefds ); /* 将 socket 1 加到 writefds */
FD_SET( 2, &writefds ); /* 将 socket 2 加到 writefds */
FD_SET( 3, &readfds ); /* 将 socket 3 加到 readfds */
select( ..., &readfds, &writefds, NULL, ...) /* 调用 select() 来检查事件 */
if (FD_ISSET( 1, &writefds )) /* 检查 socket 1 是否可写 */
send( 1, data ); /* 调用 send() 一定成功 */
if (FD_ISSET( 2, &writefds )) /* 检查 socket 2 是否可写 */
send( 2, data ); /* 调用 send() 一定成功 */
if (FD_ISSET( 3, &readfds )) /* 检查 socket 2 是否可读 */
recv( 3, data ); /* 调用 recv() 一定成功 */

不知道说得清不清楚?你明白了没有?

chchch 2003-08-21
  • 打赏
  • 举报
回复
up
大家帮帮我啊
chchch 2003-08-20
  • 打赏
  • 举报
回复
谢谢两位啊
有个问题啊,比如Accept和Recv,阻塞方式下,程序就会停到那里啊,那我怎么在线程内部关闭线程能.就算是设置了全局变量,也没有办法啊
还有就是那位高手能告诉我select怎么用啊,WSAASyncSelect我知道的,select的那几个参数我没看明白,也不知道select的作用是什么
另外,怎样在Accept和Recv之前能得到端口的状态呢?比如是否有connect请求或者数据要求接受的,然后我在调用相应函数接受,避免卡死
问题加分到60
joinrry 2003-08-18
  • 打赏
  • 举报
回复
同意楼上的!
IO端口模型都是对于非阻塞方式(异步)来说的。
smch 2003-08-18
  • 打赏
  • 举报
回复
你如果要用select的话(也可以使用WSAAsyncSelect)就成了异步方式。对于同步方式,你可以使用多线程。并且在退出的时候由程序本身连接自己。然后设置一个全局变量。在线程中的accept下面判断该变量的值来决定是退出还是继续accept其它的请求。

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧