«January 2026»
123
45678910
11121314151617
18192021222324
25262728293031


公告

本站技术贴除标明为“原创”的之外,其余均为网上转载,文中我会尽量保留原作者姓名,若有侵权请与我联系,我将第一时间做出修改。谢谢!

             ——既瑜


天气预报(南京)


我的分类(专题)

首页(183)
【趣味文摘】(22)
【五子连珠】(13)
【技术文档】(136)
【电脑技术】(6)
【疑难问题】(1)
【我的心情】(5)


最新日志
花语(中英文对照版)
各种花的花语
NTFS格式的7个精彩问答(pconli
童言无忌,有趣得一蹋
给MM修电脑的三个步骤[转载]
J2EE 面试题综合
JAVA编程规则
[转] P2P之UDP穿透NAT的原理与
[转]词法分析器
文件加密技术
一个让人发狂的PI求解C程序
[转]直线生成算法之DDA
[转]利用内核对象----互斥量实现应用
[转]如何正确的计算文件收发进度
双机调试VC程序
[转]分治法优化大整数乘法 C++实现
浮点数值的内存结构
[转]双链表实现大整数的加法与乘法[VC
拜占廷将军问题[转]
某人的挂QQ的程序源代码,虽然没用了,拿

最新回复
回复:vc中的CString的操作
回复:[转]分治法优化大整数乘法 C++
回复:[转]分治法优化大整数乘法 C++
回复:花语(中英文对照版)
回复:基本排序算法比较与选择[转载]
回复:c++中强制类型转换操作符小结
回复:c++中强制类型转换操作符小结
何必那么执着于是大头猫还是愤怒的小鸟,淡
回复:浮点数值的内存结构
回复:花语(中英文对照版)
回复:花语(中英文对照版)
回复:花语(中英文对照版)
回复:花语(中英文对照版)
回复:花语(中英文对照版)
回复:32位位图到24位位图的转换
dren, ages 16 and 20
回复:花语(中英文对照版)
回复:花语(中英文对照版)
回复:花语(中英文对照版)
回复:各种花的花语

留言板
签写新留言

不是0-1背包喔
桂花的花语``
谢谢
提议
提议

统计
blog名称:★既瑜★
日志总数:183
评论数量:636
留言数量:-25
访问次数:1427942
建立时间:2005年3月12日

链接


http://www.nju.edu.cn
http://bbs.nju.edu.cn 
http://www.t7-online.com
http://www.csdn.net
http://www.91f.net
http://www.crsky.com
我的MSN BLOG 

联系我

  OICQ:215768265
  njucs2001@hotmail.com
  erichoo1982@gmail.com

 

W3CHINA Blog首页    管理页面    写新日志    退出


[【技术文档】]winsock编程基础(很详细)[2]
既瑜(224499) 发表于 2005/3/18 20:09:01

简单的 Winsock 应用程式设计(4)         林 军 鼐  笔者在前几期的文章中已经介绍了大部份 Winsock 1.1 所提供的应用程式发 展介面;笔者也相信有读者已经开始利用这些 API 来开发自己的网路应用程式 了。但是可能仍有部份读者还是不清楚自己该先有哪些发展工具才能开发 Winsock 1.1 的应用程式? 基本上,读者当然一定要有 Microsoft C 或 Borland C 之类的编译程式 (Compiler)才能编译您的程式;至於和 Winsock 有关的档案只有两个,一个 是『winsock.h』,另一个是『winsock.lib』。这两个档案,读者们可以利用 anonymous ftp 的方式从 SEEDNET 台北主机「tpts1.seed.net.tw」的 『UPLOAD/WINKING/Winsock_Documents』目录下取得。 接著笔者要再为各位介绍剩下的几个函式,包括 select()、setsockopt()、 getsockopt(),以及变更系统的 Blocking Hook 函式时,所要用到的 WSASetBlockingHook() 和 WSAUnhookBlockingHook()。 【特殊的 select 函式】 如果写过 UNIX BSD socket 程式的读者,一定都知道这个 select() 函式是很 好用的。因为它可以帮您检查一整组(set)的 sockets 是否可以读、写资料,也 可以用来检查 socket 是否已和对方连接成功,或者是对方是否已将相对的 socket 关闭了等等。 但是在 Winsock 1.1 及 MS Windows 3.X 「非强制性多工」的环境下,它是 否仍是那麽好用呢?我们在使用它时,是否要注意些什麽呢?现在就让笔者来 告诉您吧。 ◎ select():检查一或多个 Sockets 是否处於可读、可写或错误的状态。 格  式: int PASCAL FAR select( int nfds, fd_set FAR *readfds,         fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout ) 参  数:        nfds    此参数在此并无作用         readfds 要被检查是否可读的 Sockets         writefds        要被检查是否可写的 Sockets         exceptfds       要被检查是否有错误的 Sockets         timeout 此函式该等待的时间 传回值:        成功 - 符合条件的 Sockets 总数 (若 Timeout 发生,则为 0)         失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因) 说明: 使用者可利用此函式来检查 Sockets 是否有资料可被读取, 或是有空间可以写入,或是有错误发生。 Winsock 1.1 所提供的 select() 函式与 UNIX BSD 的 select() 函式,在参数的 个数及资料型态上是一样,都有 nfds、readfds、writefds、exceptfds、及 timeout 五个参数;但是 Winsock 的 nfds 是没有作用的,有这个参数的目的,只是为了 与 UNIX BSD 的 select() 函式一致。 至於 readfds、writefds、exceptfds 同样是一组 sockets 的集合,所以您可以 同时设定许多 sockets 的号码在这三个参数里面;当然这些 sockets 必须是属於 您的这个应用程式所建立的。如果您设定的 socket 号码中有任一个不是属於您 的这个程式的话,呼叫 select() 函式便会失败(错误码为 10038 WSAENOTSOCK)。 Winsock 同样也提供了一些 macros 来让您设定或检查 readfds、writefds、 exceptfds 的值,包括有:(其中 s 代表的是某一个 socket 的号码,set 代表的就 是 readfds、writefds 或 exceptfds) 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() 一定成功 */ 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 */ 在 UNIX 系统上,我们通常会利用 select() 来做「polling」的动作,检查事 件是否发生;但是在 MS Windows 3.X 的环境下一直做 polling 的动作一定要非 常小心,不然可能会造成整个 Windows 系统停住(因为 CPU 都被您的程式占 用了);所以使用时一定要注意「控制权释放」,不然就是「不要将 timeout 设 为 {0,0}」(因为 timeout 设为 {0,0} 的话, Winsock 系统内部可能不会呼叫到 Blocking Hook 函式来释放控制权)。UNIX 系统由於是「Time Sharing」的方 式,所以并不会有类似的问题。(所谓 polling 的动作是指,您在程式中有一个 回圈,而在回圈内一直呼叫像 select 这样的函式做检查的动作) select() 除了可以用来检查 socket 是否可读写外;对於 non-blocking 的 socket 在呼叫 connect() 後,也可利用 select() 的 writefds 来检查连接是否已经成 功了(当这个 non-blocking 的 socket 被设定在 writefds,且被 select 成功时); 此外,我们亦可利用 readfds 来检查 TCP socket 连接的对方是否已经关闭了(当 此 socket 被设定在 readfds,且被 select 成功,但呼叫 recv 去收资料却 return 0 时)。         (图 1.) select 函式的几种不同用途 UNIX 系统上因为没有提供 WSAAsyncSelect() 函式,所以我们要用 select() 函式来做 polling 的动作;但是 Winsock 系统上已经有了可以设定非同步事件的 WSAAsyncSelect() 函式,为了让 MS Windows 「讯息驱动」(message driven) 的环境更有效率,读者们应该尽量使用 WSAAsyncSelect(),而少用 select() 的方 式;这也是当初为什麽要定义一个 WSAAsyncSelect() 函式的最大目的。 【变更 socket 的 options 的函式】 Winsock 1.1 也提供了一个变更 socket options 的 setsockopt() 函式;由於 options 的项目很多,笔者仅就数个较会用到的项目来解说,其馀的项目请读者 们自行研究。 ◎ setsockopt():设定 Socket 的 options。 格  式: int PASCAL FAR setsockopt( SOCKET s, int level, int optname,         const char FAR *optval, int optlen ) 参  数:        s       Socket 的识别码         level   option 设定的 level (SOL_SOCKET 或 IPPROTO_TCP)         optname option 名称         optval  option 的设定值         optlen  option 设定值的长度 传回值:        成功 - 0         失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因) 说明: 此函式用来设定 Socket 的一些 options,藉以更改其动作。可更改的 options 有:(详见 Winsock Spec. 54 页)         Option  Type -----------------------------------------------------         SO_BROADCAST    BOOL         SO_DEBUG        BOOL         SO_DONTLINGER   BOOL         SO_DONTROUTE    BOOL         SO_KEEPALIVE    BOOL         SO_LINGER       struct linger FAR*         SO_OOBINLINE    BOOL         SO_RCVBUF       int         SO_REUSEADDR    BOOL         SO_SNDBUF       int         TCP_NODELAY     BOOL (1)SO_BROADCAST -- 适用於 UDP socket。其意义是允许 UDP socket 「广播」(broadcast)讯息到网路上。 (2)SO_DONTLINGER -- 适用於 TCP socket。其意义是让 socket 在呼叫 closesocket() 关闭时,能马上 return,而不用等到资料都送完後才从函式呼叫 return;closesocket() 函式 return 後,系统仍会继续将资料全部送完後,才真正地 将这个 socket 关闭。一个 TCP socket 在开启时的预设值即是 Don't Linger。 (3)SO_LINGER -- 适用於 TCP socket 来设定 linger 值之用。如果 linger 的 值设为 0,那麽在呼叫 closesocket() 关闭 socket 时,如果该 socket 的 output buffer 中还有资料的话,将会被系统所忽略,而不会被送出,此时 closesocket() 也会马 上 return;如果 linger 值设为 n 秒,那麽系统就会在这个时间内,尝试去送出 output buffer 中的资料,时间到了或是资料送完了,才会从 closesocket() 呼叫 return。 (4)SO_REUSEADDR -- 允许 socket 呼叫 bind() 去设定一个已经用过的位址 (含 port number)。 我们就以设定某个 socket 的 linger 值为例,看看程式中该如何呼叫 setsockopt() 这个函式: struct linger Linger; Linger.l_onoff = 1;   /* 开启 linger 设定*/ Linger.l_linger = n;  /* 设定 linger 时间为 n 秒 */ setsockopt( s, SOL_SOCKET, SO_LINGER, &Linger, sizeof(struct linger) ) 相对地,如果我们想要知道目前的某个 option 的设定值,那麽就可以利用 getsockopt() 函式来取得。 ◎ getsockopt():取得某一 Socket 目前某个 option 的设定值。 格式: int PASCAL FAR getsockopt( SOCKET s, int level, int optname,         char FAR *optval, int FAR *optlen ) 参  数:        s       Socket 的识别码         level   option 设定的 level         optname option 名称         optval  option 的设定值         optlen  option 设定值的长度 传回值:        成功 - 0         失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因) 说明: 此函式用来获取目前 Socket的某些 options 设定值。 同样地,我们仍以取得某个 socket 的 linger 值为例,看一下程式中应该如何 呼叫 getsockopt(): struct linger Linger; int opt_len = sizeof(struct linger); getsockopt( s, SOL_SOCKET, SO_LINGER, &Linger, &opt_len) 【什麽是 Blocking Hook 函式及如何设定自己的 Blocking Hook 函式】 什麽是「Blocking Hook」函式呢?在解释之前,我们要先来剖析一下 Winsock 1.1 提供的 Blocking 函式(如 accept、connect 等)的内部究竟做了哪些 事? 在 Winsock Stack 的 Blocking 函式内部,除了会检查一些条件外(比如该应 用程式是否已呼叫过 WSAStartup()?传入的参数是否正确?等等),便会进入一 个类似下面的回圈: for (;;) {    /* 执行 Blocking Hook 函式 */    while (BlockingHook());       /* 检查使用者是否已经呼叫了 WSACancelBlockingCall()? */    if (operation_cancelled())       break;    /* 检查动作是否完成了? */    if (operation_complete())       break; } 现在我们可以很清楚地知道 Blocking 函式的回圈中,有三件重要的事:(1) 执行 Blocking Hook 函式(2)检查使用者是否呼叫了 WSACancelBlockingCall() 来取消此 Blocking 函式的呼叫?(3)检查此 Blocking 函式的动作是否已经完成 了? 读者们必须注意,不同的 Winsock Stack 在执行这三件事时的顺序可能会不相 同;有的 Winsock Stack 可能会先检查 Blocking 函式的动作是否已经完成了,然 後再执行 Blocking Hook 函式;所以 Blocking Hook 函式有可能不会被呼叫到。待 会解释完 Blocking Hook 函式的重点後,读者们就可以知道笔者为什麽在前面告 诉各位在使用 polling 方式时一定要非常小心了。 由上面的回圈,我们现在可以知道 Blocking Hook 函式的使用时机是让系统在 等待 Blocking 函式完成前所呼叫的,它并不是给我们自己的应用程式所使用的。 Winsock 系统本身内部就有一个预设的 Blocking Hook 函式;现在我们就来看一下 这个预设的 Blocking Hook 函式会做些什麽事? BOOL DefaultBlockingHook(void) {    MSG msg;    BOOL ret;    /* 取得下一个讯息;如果有,就处理它;如果没有,就释出控制权 */    ret = (BOOL) PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);    if (ret) {       TranslateMessage(&msg);       DispatchMessage(&msg);    }    return ret; } 哦!原来 Blocking Hook 函式中很重要的地方就是:让 Blocking 函式在等待 动作完成前能够处理其他讯息,或是释出 CPU 控制权,以便让其他的应用程式 也有执行的机会。 现在回到前面一点的地方,大家仔细想一想:如果在一个 Winsock Stack 的 Blocking 函式的回圈内,先检查 Blocking 函式的动作是否已经完成了,然後再执 行 Blocking Hook 函式的话;那麽是否就有可能不会释出 CPU 控制权来让其他的 程式有执行的机会呢?如果我们的程式中再有类似下面的一个回圈,那麽整个 Windows 环境可能就会因我们的程式而 hang 住了。 for (;;) {    FD_ZERO(&writefds);    FD_SET( s, &writefds );    timeout.tv_sec = timeout.tv_usec = 0;    n = select( 64, NULL, &writefds,  NULL, &timeout );    if ( n > 0 )      break;    if ( n == 0)  /* timeout */      continue;    ... } send( s, data ... ); 在这个回圈例子中,我们原是希望利用 select() 及 polling 的方式来检查 socket 的 output buffer 中是否尚有空间可写入资料?如果此时 output buffer 恰好满了, select() 函式中一检查到如此的情况,且 timeout 又是 {0,0},那麽就会马上 return 0,而不会呼叫到 Blocking Hook 函式来释放 CPU 控制权给 Windows 环境中的其 他程式(包括 Winsock 收送的 Protocol Stack );由於没有分配到 CPU 时间,所 以 Winsock Kernel 便无法将 output buffer 中任何资料送出;回圈中由 select() 回? 後,又回到回圈的最前面,然後又呼叫 select(),马上又 timeout......;Windows 系 统因此就 hang 住了 ! Blocking Hook 函式中除了 CPU 控制权释放的问题外,还需注意什麽呢?大 家再看一看前面 Blocking 函式的回圈;回圈内呼叫 Blocking Hook 函式是包在另 一个无穷的 while 回圈内。如果一个 Blocking Hook 函式的 return 值永远不为 0 的 话,那麽也就永远被困在这个无穷回圈内了;所以我们在设计自己的 Blocking Hook 函式时一定也要非常小心这个 return 值。 知道了 Blocking Hook 函式的用途及设计 Blocking Hook 函式该注意的地方 後,我们究竟要如何取代掉系统原有的 Blocking Hook 函式呢?那就要利用 WSASetBlockingHook() 函式了。 ◎ WSASetBlockingHook():建立应用程式指定的 blocking hook 函式。 格  式: FARPROC PASCAL FAR WSASetBlockingHook( FARPROC   lpBlockFunc ) 参  数:        lpBlockfunc     指向要装设的 blocking hook 函式的位址的指标 传回值: 指向前一个 blocking hook 函式的位址的指标 说明: 此函式让使用者可以设定他自己的 Blocking Hook 函式,以取代原先 系统预设的函式。被设定的函式将会在应用程式呼叫到「blocking」动作时执 行。唯一可在使用者指定的 blocking hook 函式中呼叫的 Winsock 介面函式只有 WSACancelBlockingCall()。 假设我们自己设计了一个 Blocking Hook 函式叫 myblockinghook(),那麽在程 式中向 Winsock 系统注册的方法如下:(其中 _hInst 代表此 task 的 Instance) FARPROC lpmybkhook = NULL; lpmybkhook = MakeProcInstance( (FARPROC)myblockinghook, _hInst) ); WSASetBlockingHook( (FARPROC)lpmybkhook );         (图 2.)设定自己的 Blocking Hook 函式 我们在设定自己的 Blocking Hook 程式後,仍可以利用 WSAUnhookBlockingHook() 函式,来取消我们设定的 Blocking Hook 函式,而变 更回原先系统内定的 Blocking Hook 函式。 ◎ WSAUnhookBlockingHook():复原系统预设的 blocking hook 函式。 格  式: int PASCAL FAR WSAUnhookBlockingHook( void ) 参  数: 无 传回值:        成功 - 0         失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因) 说明: 此函式取消使用者设定的 blocking hook 函式,而回复系统原先预 设的 blocking hook 函式。 最後笔者要再说明一点,一个应用程式所设定的 Blocking Hook 函式,只会被 这个应用程式所使用;其他的应用程式并不会执行到您设定的 Blocking Hook 函 式的。另外,若非极有必要,最好是不要任意变更系统的 Blocking Hook 函式; 因为一旦您没有设计好的话,整个 Windows 环境可能就完蛋了。         (图 3.)使用自己的 Blocking Hook 函式时该注意事项 【结语】 四期的「Winsock 应用程式设计篇」在此结束了;笔者除了介绍 Winsock API 外,也将自己亲身设计 winsock.dll 的经验与各位读者分享了;希望这几期的文 章,对於国内想要在 Winsock 1.1 环境上开发网路应用程式的读者有些许的帮 助。谢谢大家。 From: zhangwe.bbs@bbs.net.tsinghua.edu.cn Date: Wed, 22 Jan 1997 11:43:10 +0800 (CST) Message-Id: <199701220343.LAA22158@bbs.net.tsinghua.edu.cn> X-Authentication-Warning: bbs.net.tsinghua.edu.cn: bbsroot set sender to zhang we.bbs@bbs.net.tsinghua.edu.cn using -f Reply-To: zhangwe.bbs@bbs.net.tsinghua.edu.cn To: fz868@public.zz.hy.cn Subject: Winsock API 大全 (2) -- Alex 整理(转寄) X-Forwarded-By: zhangwe (乐乐) X-Disclaimer: BBS 水木清华站 对本信内容恕不负责。 Precedence: junk Content-Type: text Content-Length: 12357 Posted By: Godman (天地通) on 'Internet' Title:     Winsock API 大全 2/2 (中文) Date:      Mon Sep 25 09:26:11 1995 [Microsoft Windows-specific Extensions] (1) WSAAsyncGetHostByAddr():利用某一 host 的位址来获取该 host 的资料。      (非同步方式)     格  式: HANDLE PASCAL FAR              WSAAsyncGetHostByAddr( HWND hWnd,     unsigned int wMsg,                                     const char FAR *addr,                                     int len,                                     int type,                                     char FAR *buf,                                     int buflen );     参  数: hWnd 动作完成後,接受讯息的视窗 handle      wMsg 传回视窗的讯息      addr network 排列方式的位址      len addr 的长度      type PF_INET(AF_INET)        buf 存放 hostent 资料的区域        buflen buf 的大小     传回值: 成功 - 代表此 Async 动作的 handle      失败 - 0  (呼叫 WSAGetLastError() 可得知原因)     说明: 此函式是利用位址来获取 host 的其他资料,如 host 的名称、 别名, 位址的型态、长度等。使用者呼叫此函式时必须传入要接收资料的视窗 handle、讯息代码、资料的存放位置指标等,以便得到资料时可以通知该视窗 来使用资料。呼叫此函式後会马上回到使用者的呼叫点并传回一个 handle, 此 handle 可用来辨别此非同步动作或用来取消此非同步动作。当资料取得後, 会送一个讯息到使用者指定的视窗。 (2) WSAAsyncGetHostByName():利用某一 host 的名称来获取该 host 的资料。                               (非同步方式)     格  式: HANDLE PASCAL FAR              WSAAsyncGetHostByName( HWND hWnd,     unsigned int wMsg,                                     const char FAR *name,                                     char FAR *buf,                                     int buflen );     参  数: hWnd 动作完成後,接受讯息的视窗 handle        wMsg 传回视窗的讯息      name host 名称        buf 存放 hostent 资料的区域        buflen buf 的大小     传回值: 成功 - 代表此 Async 动作的 handle      失败 - 0  (呼叫 WSAGetLastError() 可得知原因)     说明: 此函式是利用 host 名称来获取其他的资料,如 host 的位址、 别名, 位址的型态、长度等。使用者呼叫此函式时必须传入要接收资料的视窗 handle、讯息代码、资料的存放位置指标等,以便得到资料时可以通知 该视窗来使用资料。呼叫此函式後会马上回到使用者的呼叫点并传回一 个 handle,此handle 可用来辨别此非同步动作或用来取消此非同步动 作。当资料取得後,会送一个讯息到使用者指定的视窗。 (3) WSAAsyncGetProtoByName():依照通讯协定的名称来获取该通讯协定的                               其他资料。(非同步方式)     格  式: HANDLE PASCAL FAR              WSAAsyncGetProtoByName( HWND hWnd,           unsigned int wMsg,                                      const char FAR *name,                                      char FAR *buf,                                      int buflen );     参  数: hWnd 动作完成後,接受讯息的视窗 handle        wMsg 传回视窗的讯息      name 通讯协定名称        buf 存放 protoent 资料的区域      buflen buf 的大小     传回值: 成功 - 代表此 Async 动作的 handle      失败 - 0  (呼叫 WSAGetLastError() 可得知原因)     说明: 利用通讯协定的名称来得知该通讯协定的别名、编号等资料。 使用者呼叫此函式时必须传入要接收资料的视窗 handle、讯息代码、 资料的存放位置指标等,以便得到资料时可以通知该视窗来使用资料。 呼叫此函式後会马上回到使用者的呼叫点并传回一个 handle,此  handle 可用来辨别此非同步动作或用来取消此非同步动作。当资料取得後,会 送一个讯息到使用者指定的视窗。 (4) WSAAsyncGetProtoByNumber():依照通讯协定的编号来获取该通讯协定                                 的其它资料。 (非同步方式)     格  式: HANDLE PASCAL FAR              WSAAsyncGetProtoByNumber( HWND hWnd,        unsigned int wMsg,                                        int number,                                        char FAR *buf,                                        int buflen );     参  数: hWnd 动作完成後,接受讯息的视窗 handle        wMsg 传回视窗的讯息      number 通讯协定编号,host 排列方式        buf 存放 protoent 资料的区域      buflen buf 的大小     传回值: 成功 - 代表此 Async 动作的 handle        失败 - 0  (呼叫 WSAGetLastError() 可得知原因)     说明: 利用通讯协定的编号来得知该通讯协定的名称、别名等资料。 使用者呼叫此函式时必须传入要接收资料的视窗 handle、讯息代码、资 料的存放位置指标等,以便得到资料时可以通知该视窗来使用资料。呼 叫此函式後会马上回到使用者的呼叫点并传回一个 handle,此 handle 可 用来辨别此非同步动作或用来取消此非同步动作。当资料取得後,会送 一个讯息到使用者指定的视窗。 (5) WSAAsyncGetServByName():依照服务 (service) 名称及通讯协定来                               获取该服务的其他资料。(非同步方式)     格  式: HANDLE PASCAL FAR              WSAAsyncGetServByName( HWND hWnd,     unsigned int wMsg,                                     const char FAR *name,                                     const char FAR *proto,     char FAR *buf,                                     int buflen );     参  数: hWnd 动作完成後,接受讯息的视窗 handle      wMsg 传回视窗的讯息        name 服务名称        proto 通讯协定名称         buf 存放 servent 资料的区域        buflen buf 的大小     传回值: 成功 - 代表此 Async 动作的 handle      失败 - 0  (呼叫 WSAGetLastError() 可得知原因)     说明: 利用服务名称及通讯协定来获得该服务的别名、使用的port编号等。 使用者呼叫此函式时必须传入要接收资料的视窗 handle、讯息代码、资料 的存放位置指标等,以便得到资料时可以通知该视窗来使用资料。呼叫 此函式後会马上回到使用者的呼叫点并传回一个 handle,此  handle 可 用来辨别此非同步动作或用来取消此非同步动作。当资料取得後,会送 一个讯息到使用者指定的视窗。 (6) WSAAsyncGetServByPort():依照服务 (service) 的 port 编号及通讯协定                              来获取该服务的其他资料。(非同步方式)     格  式: HANDLE PASCAL FAR              WSAAsyncGetServByPort( HWND hWnd,     unsigned int wMsg,                                     int port,                                     const char FAR *proto,                                     char FAR *buf,     int buflen );     参  数: hWnd 动作完成後,接受讯息的视窗 handle        wMsg 传回视窗的讯息        port 服务的 port 编号,network 排列方式      proto 通讯协定名称      buf 存放 servent 资料的区域      buflen buf 的大小     传回值: 成功 - 代表此 Async 动作的 handle      失败 - 0  (呼叫 WSAGetLastError() 可得知原因)     说明:利用 port 编号及通讯协定来获得该服务的名称、别名等。 使用者呼叫此函式时必须传入要接收资料的视窗 handle、讯息代码、资料 的存放位置指标等,以便得到资料时可以通知该视窗来使用资料。呼叫此函 式後会马上回到使用者的呼叫点并传回一个 handle,此  handle 可用来辨别 此非同步动作或用来取消此非同步动作。当资料取得後,会送一个讯息到使 用者指定的视窗。 (7) WSAAsyncSelect():要求某一 Socket 有事件 (event) 发生时通知使用者。     格  式: int PASCAL FAR              WSAAsyncSelect( SOCKET s, HWND hWnd,      unsigned int wMsg, long lEvent );     参  数: s Socket 的编号      hWnd 动作完成後,接受讯息的视窗 handle        wMsg 传回视窗的讯息      lEvent 应用程式有兴趣的网路事件     传回值: 成功 - 0      失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)     说明: 此函式是让使用者用来要求 Windows Sockets DLL 在侦测到某一 Socket 有网路事件时送讯息到使用者指定的视窗;网路事件是由参数 lEvent 设定。呼叫此函式会主动将该 Socket 设定为 Non-blocking 模式。 lEvent 的值可为以下之组合:(参见 WINSOCK第1.1版88、89页) FD_READ、FD_WRITE、FD_OOB、FD_ACCEPT、FD_CONNECT、 FD_CLOSE  使用者若是针对某一Socket再次呼叫此函式时,会取消对该 Socket   原先之设定。若要取消对该Socket 的所有设定,则 lEvent 的值 必须设为0。 (8) WSACancelAsyncRequest():取消某一未完成的非同步要求。     格  式: int PASCAL FAR              WSACancelAsyncRequest( HANDLE hAsyncTaskHandle );     参  数: hAsyncTaskHandle  要取消的 task handle     传回值: 成功 - 0      失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)     说明: 此函式是用来取消原先呼叫但尚未完成的WSAAsyncGetXByY(),例如 WSAAsyncGetHostByName(),的动作。参数 hAsyncTaskHandle 即为呼 叫WSAAsyncGetXByY() 时传回之值。若是原先呼叫之非同步要求已经 完成,则无法加以取消。 (9) WSACancelBlockingCall():取消目前正在进行中的 blocking 动作。     格  式: int PASCAL FAR WSACancelBlockingCall( void );     参  数: 无     传回值: 成功 - 0      失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)     说明: 此函式用来取消该应用程式正在进行中的 blocking 动作。 通常的使用时机有: (a)  Blocking 动作正在进行中,该应用程式又收到某一讯息,则可在处 理该讯息的段落中呼叫此函式。 (b)  Blocking 动作正在进行中,而 Windows Sockets 又呼叫回应用程式 的「blocking hook」函式时,在该函式内可呼叫此函式来取消 blocking 动作。 使用者必须注意,在 blocking 动作进行时,除了WSAIsBlocking() 及 WSACancelBlockingCall() 外,不可以再呼叫其它任何 Windows  Sockets DLL 提供的函式,否则会产生错误。另外若取消的 blocking  动作不是 accept() 或 select() 的话,那麽 Socket 会处於未定状态,使用者只能呼 叫 closesocket() 来关闭该 Socket,而不该再对它做任何动作。 (10) WSACleanup():结束 Windows Sockets DLL 的使用。      格  式: int PASCAL FAR WSACleanup( void );      参  数: 无      传回值:成功 - 0      失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)      说明: 应用程式在使用 Windows Sockets DLL 时必须先呼叫 WSAStartup() 来向 Windows Sockets DLL 注册;当应用程式不再需要使用 Windows Sockets DLL 时,须呼叫此一函式来注销使用,以便释放其占用的资源。 (11) WSAGetLastError():获取最後一次错误发生时的讯息。      格  式: int PASCAL FAR WSAGetLastError( void );      参  数: 无      传回值: Windows Sockets API 最後发生的错误码      说明: 此函式用来获取最後一次网路错误发生时的讯息。 (12) WSAIsBlocking():检查是否有 blocking 动作正在进行中。      格  式: BOOL PASCAL FAR WSAIsBlocking( void );      参  数: 无      传回值: TRUE  - 有 blocking 动作正在进行中       FALSE - 没有 blocking 动作      说明: 此函式是给使用者用来检查目前是否有 blocking 动作正在进行中。 由於blocking 动作进行时,应用程式仍可能收到其它的讯息,所以使用 者可以呼叫此一函式来检查 blocking 动作是否完成了,以免再未完成前 呼叫了不当的函式。 (13) WSASetBlockingHook():建立应用程式指定的 blocking hook 函式。      格  式: FARPROC PASCAL FAR               WSASetBlockingHook( FARPROC lpBlockFunc );      参  数: lpBlockfunc  指向要装设的 blocking hook 函式的位址的指标      传回值: 指向前一个 blocking hook 函式的位址的指标      说明: 此函式让使用者可以设定他自己的函式,以取代原先系统预设的函 式。被设定的函式将会在应用程式呼叫到「blocking」动作时执行。 唯一可在使用者指定的 blocking hook 函式中呼叫的 Windows   Sockets 介面函式只有 WSACancelBlockingCall()。 (14) WSASetLastError():设定错误码;此设定值可用 WSAGetLastError() 获得。      格  式: void PASCAL FAR WSASetLastError( int iError );      参  数: iError   欲设定的错误码      传回值: 无      说明: 此函式可用来设定错误码,以被稍後的 WSAGetLastError() 获得; 但若是有其他的Windows Sockets 函式被呼叫到,则此函式设定的错误值会 被更改掉。 (15) WSAStartup():连结应用程式与 Windows Sockets DLL 的第一个函式。      格  式: int PASCAL FAR WSAStartup( WORD wVersionRequested,          LPWSADATA lpWSAData );      参  数: wVersionRequested 可使用的 Windows Sockets API 最高版本              lpWSAData 指向 WSADATA 资料的指标       struct WSAData { WORD wVersion; WORD wHighVersion; char szDescription[WSADESCRIPTION_LEN+1]; char szSystemStatus[WSASYSSTATUS_LEN+1]; unsigned short iMaxSockets; unsigned short iMaxUdpDg; char FAR * lpVendorInfo;       };      传回值: 成功 - 0         失败 - WSASYSNOTREADY / WSAVERNOTSUPPORTED / WSAEINVAL      说明: 此函式「必须」是应用程式呼叫到 Windows Sockets DLL 函式中 的第一个,也唯有此函式呼叫成功後,才可以再呼叫其他 Windows  Sockets DLL 的函式。此函式亦让使用者可以指定要使用的 Windows Sockets API 版本,及获取设计者的一些资讯。 (* 目前只提供 WINSOCK 第 1.1 版的功能) (16) WSAUnhookBlockingHook():复原预设的 blocking hook 函式。      格  式: int PASCAL FAR WSAUnhookBlockingHook( void );      参  数: 无      传回值: 成功 - 0       失败 - SOCKET_ERROR (呼叫 WSAGetLastError() 可得知原因)      说明: 此函式取消使用者设定的 blocking hook 函式,而回复原先预设的 blocking hook 函式。

阅读全文(3224) | 回复(0) | 编辑 | 精华


发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)

站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.543 second(s), page refreshed 144813189 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号