Programming °æ (¾«»ªÇø)

·¢ÐÅÈË: superman (·çÓêÎÞ×è), ÐÅÇø: Programming
±ê  Ìâ: ¼òµ¥µÄ Winsock Ó¦ÓóÌʽÉè¼Æ£¨2)(fwd) (תÔØ)
·¢ÐÅÕ¾: ×϶¡Ïã (Thu Oct  9 21:55:43 1997)

¡¾ ÒÔÏÂÎÄ×ÖתÔØ×Ô Winsock ÌÖÂÛÇø ¡¿
¡¾ Ô­ÎÄÓÉ topcon Ëù·¢±í ¡¿
·¢ÐÅÕ¾: °×ɽºÚË® (Tue Apr 23 21:28:45 1996)

¼òµ¥µÄ Winsock Ó¦ÓóÌʽÉè¼Æ£¨2£©

        ÁÖ ¾ü Ø¾

ÔÚÇ°Ò»ÆÚµÄÎÄÕÂÖУ¬±ÊÕßΪ´ó¼Ò½éÉÜÁËÈçºÎÔÚ Winsock »·¾³Ï£¬½¨Á¢Ö÷´Ó
¼Ü¹¹£¨Client/Server£©µÄ TCP socket µÄÁ¬½Ó½¨Á¢Óë¹Ø±Õ£»½ñÌì±ÊÕß½«¼ÌÐøΪ´ó¼Ò
½éÉÜÈçºÎÀûÓàTCP socket À´ÊÕËÍ×ÊÁÏ£¬²¢Ïêϸ½â˵ WSAAsyncSelect º¯Ê½ÖеÄ
FD_READ ¼° FD_WRITE Ê¼þ£¨±ÊÕßÔø·¢ÏÖÓÐÏ൱¶àÈ˶ÔÕâÁ½¸öʼþÉõ²»ÁË
½â£©¡£

ÏàÐŶÁÕßÃÇÒѾ­ÖªµÀ TCP socket µÄÁ¬½ÓÊÇÔÚ Client ¶Ëºô½Ð connect º¯Ê½³É
¹¦£¬ÇÒ Server ¶Ëºô½Ð accept º¯Ê½áᣬ²ÅËãÍêÈ«½¨Á¢³É¹¦£»µ±Á¬½Ó½¨Á¢³É¹¦áᣬ
Client ¼° Server Ò²¾Í¿ÉÒÔÀûÓÃÕâ¸öÁ¬½Ó³É¹¦µÄ socket À´´«ËÍ×ÊÁϵ½¶Ô·½£¬»òÊÇ
ÊÕÈ¡¶Ô·½Ë͹ýÀ´µÄ×ÊÁÏÁË¡£


        £¨Í¼ 1. TCP socket µÄ×ÊÁÏÊÕËÍ£©

ÔÚ½éÉÜ×ÊÁϵÄÊÕËÍÇ°£¬±ÊÕßÏȽéÉÜһϠTCP socket Óë UDP socket ÔÚ´«ËÍ×Ê
ÁÏʱµÄÌØÐÔ£º

Stream (TCP) Socket Ìṩ¡¸Ë«Ïò¡¹¡¢¡¸¿É¿¿¡¹¡¢¡¸ÓдÎÐò¡¹¡¢¡¸²»Öظ²¡¹Ö®
×ÊÁÏ´«ËÍ¡£

Datagram (UDP) Socket ÔòÌṩ¡¸Ë«Ïò¡¹Ö®¹µÍ¨£¬µ«Ã»ÓС¸¿É¿¿¡¹¡¢¡¸ÓдÎ
Ðò¡¹¡¢¡¸²»Öظ²¡¹µÈÖ®±£Ö¤£» ËùÒÔʹÓÃÕß¿ÉÄÜ»áÊÕµ½ÎÞ´ÎÐò¡¢Öظ²Ö®×ÊÁÏ£¬ÉõÖÁ
×ÊÁÏÔÚ´«Êä¹ý³ÌÖÐÒ²¿ÉÄÜ»áÒÅ©¡£

ÓÉ춠UDP Socket ÔÚ´«ËÍ×ÊÁÏʱ£¬²¢²»±£Ö¤×ÊÁÏÄÜÍêÕûµØËÍ´ï¶Ô·½£¬ËùÒÔÎÒ
Ãdz£ÓõÄһЩӦÓóÌʽ£¨Èç telnet¡¢mail¡¢ftp¡¢news...µÈ£©¶¼ÊDzÉÓàTCP
Socket£¬ÒÔ±£Ö¤×ÊÁϵÄÕýÈ·ÐÔ¡££¨TCP ¼° UDP ·â°üµÄ´«ËÍЭ¶¨²»ÔÚÎÒÃÇÌÖÂÛ¡õ
Χ£¬ÏëÒªÁ˽âµÄ¶ÁÕßÃÇ£¬Çë×ÔÐвο¼Ïà¹ØÊé¼®£©

TCP ¼° UDP Socket ¶¼ÊÇË«ÏòµÄ£¬ËùÒÔÎÒÃÇÊÇÀûÓÃͬһ¸ö Socket À´×ö´«Ëͼ°
ÊÕÈ¡×ÊÁϵĶ¯×÷£»Ò»°ãÑÔ TCP Socket µÄ×ÊÁÏËÍ¡¢ÊÕÊǺô½Ð send() ¼° recv() ÕâÁ½
¸öº¯Ê½À´´ï³É£¬¶ø UDP Socket ÔòÊÇÓàsendto() ¼° recvfrom() ÕâÁ½¸öº¯Ê½¡£²»¹ý
TCP Socket Ò²¿ÉÓàsendto() ¼° recvfrom() º¯Ê½£¬UDP Socket Í¬Ñù¿ÉÓàsend() ¼°
recv() º¯Ê½£»ÕâÒ»µãÎÒÃÇÉÔááÔÙ¼ÓÒÔ½âÊÍ¡£

ÏÖÔÚÎÒÃÇÏÈ¿´Ò»Ï send() ¼° recv() µÄº¯Ê½ËµÃ÷£¬²¢»Øµ½ÎÒÃǵÄÇ°Ò»ÆÚ³Ì
ʽ¡£

¡ò send()£ºÊ¹ÓÃÁ¬½Óʽ£¨connected£©µÄ Socket ´«ËÍ×ÊÁÏ¡£
¸ñ  Ê½£º int PASCAL FAR send( SOCKET s, const char FAR *buf,
        int len, int flags );
²Î  Êý£º        s       Socket µÄʶ±ðÂë
        buf     ´æ·ÅÒª´«Ë͵Ä×ÊÁϵÄÔÝ´æÇø
        len     buf µÄ³¤¶È
        flags   ´Ëº¯Ê½±»ºô½ÐµÄ·½Ê½
´«»ØÖµ£º        ³É¹¦ - ËͳöµÄ×ÊÁϳ¤¶È
        Ê§°Ü - SOCKET_ERROR (ºô½Ð WSAGetLastError() ¿ÉµÃÖªÔ­Òò)
˵Ã÷£º ´Ëº¯Ê½ÊÊÓÃì¶Á¬½ÓʽµÄ Datagram »ò Stream Socket À´´«ËÍ×ÊÁÏ¡£ ¶Ô
Datagram Socket ÑÔ£¬ÈôÊÇ datagram µÄ´óС³¬¹ýÏÞÖÆ£¬Ôò½«²»»áËͳöÈκÎ×ÊÁÏ£¬²¢
»á´«»Ø´íÎóÖµ¡£¶Ô Stream Socket ÑÔ£¬Blocking Ä£Ê½Ï£¬ÈôÊÇ´«ËÍ (transport) ÏµÍ³
ÄÚÖ®´¢´æ¿Õ¼ä£¨output buffer£©²»¹»´æ·ÅÕâЩҪ´«Ë͵Ä×ÊÁÏ£¬send() ½«»á±» block
ס£¬Ö±µ½×ÊÁÏËÍÍêΪֹ£»Èç¹û¸Ã Socket ±»É趨Ϊ Non-Blocking Ä£Ê½£¬ÄÇ÷ὫÊÓÄ¿
Ç°µÄ output buffer ¿Õ¼äÓжàÉÙ£¬¾ÍËͳö¶àÉÙ×ÊÁÏ£¬²¢²»»á±» block ×¡¡£Ê¹ÓÃÕßÒàÐë
×¢Òâ send()º¯Ê½Ö´ÐÐÍê³É£¬²¢²»±íʾ×ÊÁÏÒѾ­³É¹¦µØË͵ֶԷ½ÁË£¬¶øÊÇÒѾ­·Åµ½
ϵͳµÄ output buffer ÖУ¬µÈ´ý±»Ëͳö¡£ flags µÄÖµ¿ÉÉèΪ 0 »ò MSG_DONTROUTE
¼° MSG_OOB µÄ×éºÏ¡£(²Î¼û WINSOCKµÚ1.1°æ48Ò³)

¡ò recv()£º×Ô Socket ½ÓÊÕ×ÊÁÏ¡£
¸ñ  Ê½£º int PASCAL FAR recv( SOCKET s, char FAR *buf, int len,  int flags );
²Î  Êý£º        s       Socket µÄʶ±ðÂë
        buf     ´æ·Å½ÓÊÕµ½µÄ×ÊÁϵÄÔÝ´æÇø
        len     buf µÄ³¤¶È
        flags   ´Ëº¯Ê½±»ºô½ÐµÄ·½Ê½
´«»ØÖµ£º        ³É¹¦ - ½ÓÊÕµ½µÄ×ÊÁϳ¤¶È (Èô¶Ô·½ Socket Òѹرգ¬ÔòΪ 0)
        Ê§°Ü - SOCKET_ERROR (ºô½Ð WSAGetLastError() ¿ÉµÃÖªÔ­Òò)
˵Ã÷£º ´Ëº¯Ê½ÓÃÀ´×ÔÁ¬½ÓʽµÄ Datagram Socket »ò Stream Socket ½ÓÊÕ×ÊÁÏ¡£
¶Ô Stream Socket ÑÔ£¬ÎÒÃÇ¿ÉÒÔ½ÓÊÕµ½Ä¿Ç° input buffer ÄÚÓÐЧµÄ×ÊÁÏ£¬µ«ÆäÊýÁ¿
²»³¬¹ý len µÄ´óС¡£ÈôÊÇ´Ë Socket É趨 SO_OOBINLINE£¬ÇÒÓРout-of-band µÄ×Ê
ÁÏδ±»¶ÁÈ¡£¬ÄÇ÷áÖ»ÓРout-of-band µÄ×ÊÁϱ»È¡³ö¡£¶Ô Datagram Socket ÑÔ£¬Ö»È¡
³öµÚÒ»¸ö datagram£»ÈôÊǸàdatagram ´ó ì¶Ê¹ÓÃÕßÌṩµÄ´¢´æ¿Õ¼ä£¬ÄÇ÷áÖ»ÓиÿÕ
¼ä´óСµÄ×ÊÁϱ»È¡³ö£¬¶àâŵÄ×ÊÁϽ«ÒÅʧ£¬Çһظ²´íÎóµÄѶϢ¡£ÁíÍâÈç¹û  Socket
Ϊ Blocking Ä£Ê½£¬ÇÒÄ¿Ç° input buffer ÄÚûÓÐÈκÎ×ÊÁÏ£¬Ôò recv() ½« block µ½ÓÐÈÎ
ºÎ×ÊÁϵ½´ïΪֹ£»Èç¹ûΪ Non-Blocking Ä£Ê½£¬ÇÒ input buffer ÎÞÈκÎ×ÊÁÏ£¬Ôò»áÂí
Éϻظ²´íÎó¡£²ÎÊý flags µÄÖµ¿ÉΪ 0 »ò MSG_PEEK¡¢MSG_OOB µÄ×éºÏ£»
MSG_PEEK ´ú±í½«×ÊÁÏ¿½±´µ½Ê¹ÓÃÕßÌṩµÄ buffer£¬µ«ÊÇ×ÊÁϲ¢²»´ÓϵͳµÄ input
buffer ÖÐÒÆ×ߣ»0 Ôò±íʾ¿½±´²¢ÒÆ×ß¡£(²Î¿¼ WINSOCK µÚ1.1°æ41 Ò³)

¡¾Server ¶ËµÄ×ÊÁÏÊÕËͼ°¹Ø±Õ Socket¡

ÔÚÇ°Ò»ÆÚÖУ¬ÎÒÃÇ˵½¨Á¢µÄÊÇÒ»¸ö Asynchronous Ä£Ê½µÄ Server£»³ÌʽÖУ¬
ÎÒÃÇÔø¶Ô listen_sd Õâ¸ö Socket ºô½Ð WSAAsyncSelect() º¯Ê½£¬²¢É趨
FD_ACCEPT Ê¼þ£¬ËùÒÔµ± Client ÓëÎÒÃÇÁ¬½Óʱ£¬ÏµÍ³»á´«¸øÎÒÃÇÒ»¸ö
ASYNC_EVENT Ñ¶Ï¢£¨Çë²Î¼ûÇ°Ò»ÆÚÎÄÕÂÄÚÈÝ£©£»ÎÒÃÇÔÚÊÕµ½Ñ¶Ï¢²¢ÅжÏÊÇ
FD_ACCEPT Ê¼þ£¬ì¶ÊǺô½Ð accept() À´½¨Á¢Á¬½Ó¡£

my_sd = accept(listen_sd, (struct sockaddr far *)&sa, &sa_len)

ÎÒÃÇÔÚºô½ÐÍê accept() º¯Ê½£¬³É¹¦µØ½¨Á¢ÁË Server ¶ËÓë Client ¶ËµÄÁ¬½Óáᣬ
´Ëʱ±ã¿ÉÀûÓÃн¨µÄ Socket£¨my_sd£©À´ÊÕËÍ×ÊÁÏÁË¡£ÓÉì¶ÎÒÃÇͬÑùÏ£ÍûÓÃ
Asynchronous µÄ·½Ê½£¬Òò´ËÒªÔÙÀûÓàWSAAsyncSelect() º¯Ê½À´°ïн¨µÄ
Socket É趨һЩʼþ£¬ÒÔ±ãʼþ·¢Éúʱ Winsock Stack ÄÜÖ÷¶¯Í¨ÖªÎÒÃÇ¡£ÓÉì¶ÎÒ
ÃǵĠServer ÊDZ»¶¯µÄ½ÓÊÜ Client µÄÒªÇó£¬È»ááÔÙ×ö´ð¸²£¬ËùÒÔÎÒÃÇÉ趨
FD_READ Ê¼þ£»ÎÒÃÇҲϣÍû Winsock Stack ÔÚÖªµÀ Client ¹Ø±Õ Socket Ê±£¬ÄÜÖ÷
¶¯Í¨ÖªÎÒÃÇ£¬ËùÒÔͬʱҲÉ趨 FD_CLOSE Ê¼þ¡££¨¶ÁÕßÐë×¢Ò⣬ÎÒÃÇÉ趨ʼþ
µÄ Socket ºÅÂëÊǺô½Ð accept áá´«»ØµÄРSocket ºÅÂ룬¶ø²»ÊÇÔ­ÏȼàÌý״̬µÄ
Socket ºÅÂ룩

WSAAsyncSelect(my_sd, hwnd, ASYNC_EVENT, FD_READ|FD_CLOSE)

ÔÚÕâÀÎÒÃÇͬÑùÊÇÀûÓàhwnd Õâ¸öÊÓ´°¼° ASYNC_EVENT Õâ¸öѶϢ£»ÔÚ
Ç°ÎÄÖУ¬±ÊÕßÔø¸æË߸÷룬ÔÚÊÕµ½ ASYNC_EVENT Ñ¶Ï¢Ê±£¬ÎÒÃÇ¿ÉÒÔÀûÓÃ
WSAGETSELECTEVENT(lParam) À´ÅжϾ¿¾¹ÊÇÄÄһʼþ£¨FD_READ »ò
FD_CLOSE£©·¢ÉúÁË£»ËùÒÔ²¢²»»á»ìÏý¡£ÄÇÎÒÃǵ½µ×ÔÚʲ÷áʱºò»áÊÕµ½
FD_READ »ò FD_CLOSE Ê¼þµÄѶϢÄØ£¿

¡¾FD_READ Ê¼þ¡¿

ÎÒÃÇ»áÊÕµ½ FD_READ Ê¼þ֪ͨÎÒÃÇÈ¥¶ÁÈ¡×ÊÁϵÄÇé¿öÓР£º

£¨1£©ºô½Ð WSAAsyncSelect º¯Ê½À´¶Ô´Ë Socket É趨 FD_READ Ê¼þʱ£¬
input buffer ÖÐÒÑÓÐ×ÊÁÏ¡£
£¨2£©Ô­ÏÈϵͳµÄ input buffer Êǿյģ¬µ±ÏµÍ³ÔÙÊÕµ½×ÊÁÏʱ£¬»á֪ͨÎÒÃÇ¡£
£¨3£©Ê¹ÓÃÕߺô½Ð recv »ò recvfrom º¯Ê½£¬´Ó input buffer ¶ÁÈ¡×ÊÁÏ£¬µ«ÊDz¢
ûÓÐÒ»´Î½«×ÊÁ϶Á¹â£¬´Ëʱ»áÔÙÇý¶¯Ò»¸ö FD_READ Ê¼þ£¬±íʾÈÔÓÐ×ÊÁÏÔÚ
input buffer ÖС£

¶ÁÕß±ØÐë×¢Ò⣺Èç¹ûÎÒÃÇÊÕµ½ FD_READ Ê¼þ֪ͨµÄѶϢ£¬µ«ÊÇÎÒÃǹÊÒâ
²»ºô½Ð recv »ò recvfrom À´¶ÁÈ¡×ÊÁϵĻ°£¬¶ûááϵͳÓÖÊÕµ½×ÊÁÏʱ£¬²¢²»»áÔÙ´Î
֪ͨÎÒÃÇ£¬Ò»¶¨ÒªµÈÎÒÃǺô½ÐÁË recv »ò recvfrom áᣬ²ÅÓпÉÄÜÔÙÊÕµ½
FD_READ µÄʼþ֪ͨ¡£

¡¾FD_CLOSE Ê¼þ¡¿

µ±ÏµÍ³ÖªµÀ¶Ô·½ÒѾ­½« Socket ¹Ø±ÕÁ˵ÄÇé¿öÏ£¨ÊÕµ½ FIN Í¨Öª£¬²¢ºÍ¶Ô·½
×ö¹Ø±Õ¶¯×÷µÄ hand-shaking£©£¬ÎÒÃÇ»áÊÕµ½ FD_CLOSE µÄʼþ֪ͨ£¬ÒÔ±ãÎÒ
ÃÇÒ²Äܽ«Õâ¸öÏà¶ÔµÄ Socket ¹Ø±Õ¡£FD_CLOSE Ê¼þÖ»»á·¢Éú춠TCP Socket£¬Òò
ΪËüÊÇ connection-oriented£»¶Ô춠connectionless µÄ UDP Socket£¬¼´Ê¹ÉèÁË
FD_CLOSE£¬Ò²²»»áÓÐ×÷Óõġ£

³ÌʽÖУ¬µ± Client ¶ËËÍÒ»¸öÒªÇó£¨request£©À´Ê±£¬ÏµÍ³»áÒÔ
ASYNC_EVENT Ñ¶Ï¢Í¨ÖªÎÒÃǵĠhwnd ÊÓ´°£»ÎÒÃÇÔÚÀûÓÃ
WSAGETSELECTEVENT(lParam) ¼° WSAGETSELECTERROR(lParam) ÖªµÀÊÇ
FD_READ Ê¼þ¼°¼ì²éÎÞÎóáᣬ±ãºô½Ð recv() º¯Ê½À´ÊÕÈ¡ Client ¶ËËÍÀ´µÄ×ÊÁÏ¡£

recv(wParam, &data, sizeof(data), 0)

±ÊÕßÔÚÇ°Ò»ÆÚÎÄÕÂÖÐÒ²ÔøÌᵽ˵£¬FD_XXXX Ê¼þ·¢Éú£¬ÊÕµ½Ñ¶Ï¢Ê±£¬ÊÓ
´° handle ±»ºô½ÐʱµÄ²ÎÊý wParam ´ú±íµÄ¾ÍÊÇʼþ·¢ÉúµÄ Socket ºÅÂ룬ËùÒÔ´Ë
´¦ wParam µÄÖµÒ²¾ÍÊÇÇ°ÃæÌáµ½µÄ my_sd Õâ¸ö Socket ºÅÂë¡£recv() µÄµÚËĸö²Î
ÊýÉèΪ 0£¬±íʾÎÒÃÇÒª½«×ÊÁÏ´ÓϵͳµÄ input buffer ÖжÁÈ¡²¢ÒÆ×ß¡£

ÊÕµ½ÒªÇóáᣬÎÒÃÇÒª´ð¸² Client ¶Ë£¬Ò²¾ÍÊÇÒªËÍ×ÊÁϸø Client£»ÕâʱÎÒÃǾÍ
ÒªÀûÓàsend() Õâ¸öº¯Ê½ÁË¡£

ÎÒÃÇÏȽ«×ÊÁϷŵ½ data Õâ¸ö×ÊÁÏÔÝ´æÇø£¬È»ááºô½Ð send() ½«ËüËͳö£¬ÎÒÃÇ
ÀûÓõÄÒ²ÊÇ wParam (my_sd) Õâ¸öͬÑùµÄ Socket À´×ö´«Ë͵Ķ¯×÷£¬ÒòΪËüÊÇË«Ïò
µÄ¡£

send(wParam, &data, strlen(data), 0)

Server Óë Client ÊÕËÍ×ÊÁÏÒ»¶Îʱ¼äáᣨ×ÊÁÏÈ«²¿ÊÕËÍÍê±Ï£©£¬Èç¹û Client ¶Ë
ÏȺô½Ð closesocket() ½«ËüÄǶ˵ĠSocket ¹Ø±Õ£¬ÄÇ÷áϵͳÔÚÖªµÀáᣬ»á֪ͨÎÒÃÇ
Ò»¸ö FD_CLOSE Ê¼þµÄѶϢ£¬´ËʱÎÒÃÇÒ²¿ÉÒÔºô½Ð closesocket() ½«ÎÒÃÇÕâ¶ËµÄ
Socket ¹Ø±ÕÁË£»µ±È»ÎÒÃÇÒ²¿ÉÒÔºô½Ð closesocket() ÏÈÖ÷¶¯¹Ø±ÕÎÒÃÇÕâ¶ËµÄ
Socket¡£

¡¾Client ¶ËµÄ×ÊÁÏÊÕËͼ°¹Ø±Õ Socket¡¿

ÎÒÃÇÀý×ӵĠClient ÊDzɠBlocking Ä£Ê½£¬ËùÒÔÔÚºô½Ð connect() º¯Ê½Óë Server
Á¬½Óʱ£¬¿ÉÄÜ»áµÈÒ»ÏÂ×Ӳųɹ¦£»connect() º¯Ê½·µ»ØáᣬÇÒÎÞ´íÎó·¢ÉúµÄ»°£¬
Client Óë Server ¶ËµÄ TCP socket Á¬½Ó¾ÍËã³É¹¦ÁË¡£Õâʱ£¬ÎÒÃDZã¿ÉÀûÓÃÕâ¸öÁ¬
½Ó³É¹¦µÄ Socket À´ËÍÊÕ×ÊÁÏÁË¡£ÓÉì¶ÎÒÃDz¢Ã»ÓÐÒªÉ趨Ϊ Asynchronous Ä£Ê½£¬
ËùÒÔÒ²²»Óúô½Ð WSAAsyncSelect() À´É趨ʼþ¡£

Client ¶Ëͨ³£ÊÇ»áÏÈÖ÷¶¯·¢³öÒªÇóµ½ Server ¶Ë£¬Òò´ËÎÒÃǺô½Ð send() À´´«ËÍ
´ËÒ»×ÊÁÏ¡£ÎÒÃǵÄ×ÊÁÏÁ¿ºÜС£¬ËùÒÔ²¢²»»á±» send() º¯Ê½ Block ×¡£»²»¹ýÈç¹û
ÄúÒªË͵Ä×ÊÁÏÁ¿ºÜ´ó£¬ÄÇ÷á¿ÉÄÜ»áµÈÒ»¶Îʱ¼ä²Å»á×Ô send() º¯Ê½·µ»Ø£»Ò²¾ÍÊÇ
˵±ØÐëµÈ×ÊÁ϶¼·Åµ½ÏµÍ³µÄ output buffer áá²Å»á·µ»Ø£»ÕâÊÇÒòΪÎÒÃÇ Client µÄ
Socket ÊÇ×èÀ¹Ä£Ê½¡£Èç¹ûÎÒÃÇÓõÄÊÇ·Ç×èÀ¹Ä£Ê½µÄ Socket£¬ÄÇ÷á send() º¯Ê½»á
ÊÓϵͳµÄ output buffer µÄ¿Õ¼äÓжàÉÙ£¬Ö»¿½±´ÄÇ÷á¶àµÄ×ÊÁϵ½ output buffer£¬È»
áá¾Í·µ»Ø£¬²¢¸æ֪ʹÓÃÕßËͳöÁ˶àÉÙ×ÊÁÏ£¬²¢²»ÐëµÈËùÓÐ×ÊÁ϶¼·Åµ½ output
buffer ²Å·µ»Ø¡£

ÎÒÃǽ«ÒªÇó·ÅÔÚ data ×ÊÁÏÔÝ´æÇø£¬È»ááºô½Ð send() ½«ÒªÇóËͳö¡£×ÊÁÏËͳö
áᣬÎÒÃǺô½Ð recv() À´µÈ´ý Server ¶ËµÄ´ð¸²¡£

send(mysd, data, strlen(data), 0)

recv(mysd, &data, sizeof(data), 0)

ÓÉì¶ÎÒÃÇ Client ¶ËÊÇ Blocking Ä£Ê½£¬ËùÒÔ recv() »áÒ»Ö± Block ×¡£¬Ö±µ½ÏÂ
ÁеÄÇé¿öÖ®Ò»·¢Éú£¬²Å»á·µ»Ø¡£

£¨1£©Server ¶ËËÍÀ´×ÊÁÏ¡££¨´Ëʱ return ÖµÊǶÁÈ¡µÄ×ÊÁϳ¤¶È£©
£¨2£©Server ¶Ë½«Ïà¶ÔµÄ Socket ¹Ø±ÕÁË¡££¨´ËʱµÄ return Öµ»áÊÇ 0£©
£¨3£©Client ¶Ë×Ô¼ººô½Ð WSACancelBlockingCall() À´È¡Ïû recv() µÄºô½Ð¡£
£¨´Ëʱ return ÖµÊÇ SOCKET_ERROR ´íÎ󣬴íÎóÂë 10004 WSAEINTR£©

ͬÑùµØ£¬×ÊÁÏÈ«²¿ËÍÊÕÍê±ÏáᣬÎÒÃÇÒ²ºô½Ð closesocket() À´½« Socket ¹Ø
±Õ¡£

¡ò WSACancelBlockingCall()£ºÈ¡ÏûÄ¿Ç°ÕýÔÚ½øÐÐÖеĠblocking ¶¯×÷¡£
¸ñ  Ê½£º int PASCAL FAR WSACancelBlockingCall( void );
²Î  Êý£º ÎÞ
´«»ØÖµ£º        ³É¹¦ - 0
        Ê§°Ü - SOCKET_ERROR (ºô½Ð WSAGetLastError() ¿ÉµÃÖªÔ­Òò)
˵Ã÷£º  ´Ëº¯Ê½ÓÃÀ´È¡Ïû¸ÃÓ¦ÓóÌʽÕýÔÚ½øÐÐÖеĠblocking ¶¯×÷¡£Í¨³£µÄ
ʹÓÃʱ»úÓУº(a) Blocking ¶¯×÷ÕýÔÚ½øÐÐÖУ¬¸ÃÓ¦ÓóÌʽÓÖÊÕµ½Ä³Ò»Ñ¶Ï¢
£¨Mouse¡¢Keyboard¡¢Timer µÈ£©£¬Ôò¿ÉÔÚ´¦Àí¸ÃѶϢµÄ¶ÎÂäÖкô½Ð´Ëº¯Ê½¡£(b)
Blocking ¶¯×÷ÕýÔÚ½øÐÐÖУ¬¶ø Windows Sockets ÓÖºô½Ð»ØÓ¦ÓóÌʽµ
¡¸blocking hook¡¹º¯Ê½Ê±£¬Ôڸú¯Ê½Äڿɺô½Ð´Ëº¯Ê½À´È¡Ïû blocking ¶¯×÷¡£
ʹÓÃÕß±ØÐë×¢Ò⣬ÔÚijһ Winsock blocking º¯Ê½¶¯×÷½øÐÐʱ£¬³ýÁË
WSAIsBlocking() ¼° WSACancelBlockingCall() Í⣬²»¿ÉÒÔÔÙºô½ÐÆäËüÈκÎ
Windows Sockets DLL ÌṩµÄº¯Ê½£¬·ñÔò»á²úÉú´íÎó¡£ÁíÍâÈôÈ¡ÏûµÄ
blocking ¶¯×÷²»ÊÇ accept() »ò select() µÄ»°£¬ÄÇ÷á¸Ã Socket ¿ÉÄܻᴦì¶Î´¶¨
״̬£¬Ê¹ÓÃÕß×îºÃÊǺô½Ð closesocket() À´¹Ø±Õ¸Ã Socket£¬¶ø²»¸ÃÔÙ¶ÔËü×öÈÎ
ºÎ¶¯×÷¡£


£¨Í¼ 2.£©demoserv Óë democlnt ÔÚ×ʲ߻á WinKing ÉÏÊÕËÍ×ÊÁϵĻ­Ãæ


£¨Í¼ 3.£©demoserv Óë democlnt ÔÚ×ʲ߻á WinKing ÉϹرՠSocket ááµÄ»­Ãæ

½éÉÜÍêÁË TCP Socket µÄ×ÊÁÏÊÕËÍ£¬±ÊÕß½ÓÖøΪ¶ÁÕß½éÉÜ sendto() ¼°
recvfrom() ÕâÁ½¸öº¯Ê½£¬ÒÔ¼°Ðí¶àÈË¿ÉÄܺÜÈÝÒ׸ã´íµÄ FD_WRITE Ê¼þ¡£

¡¾sendto ¼° recvfrom º¯Ê½¡¿

Ò»°ãÑÔ£¬TCP Socket Ê¹ÓõÄÊÇ send() ¼° recv() ÕâÁ½¸öº¯Ê½£»¶ø UDP Socket
ÓõÄÊÇ sendto() ¼° recvfrom() º¯Ê½¡£ÕâÊÇÒòΪ TCP ÊÇ Connection-oriented£¬±ØÐë
×öÍê Socket ÕæÕýµÄÁ¬½Ó³ÌÐòáᣬ²Å¿ÉÒÔ¿ªÊ¼ÊÕËÍ×ÊÁÏ£¬´ËʱϵͳÒѾ­ÖªµÀÁËÁ¬
½ÓµÄ¶Ô·½£¬ËùÒÔÎÒÃDz»ÓÃÔÙÖ¸¶¨×ÊÁÏÒªË͵½ÄÄÀï¡£¶ø UDP ÊÇ Connectionless£¬
ÊÕËÍ×ÊÁϵÄË«·½²¢Ã»Óн¨Á¢ÕæÕýµÄÁ¬½Ó£¬ËùÒÔÎÒÃÇÒªÀûÓàsendto() ¼° recvfrom()
À´Ö¸¶¨ÊÕ×ÊÁϵĶԷ½¼°»ñÖªÊÇË­ËÍ×ÊÁϸøÎÒÃÇ¡

 TCP Socket Ò²¿ÉÒÔÓàsendto() ¼° recvfrom() À´ËÍÊÕ×ÊÁÏ£¬Ö»ÊÇ´ËʱÕâÁ½¸ö
º¯Ê½µÄ×îááÁ½¸ö²ÎÊýûÓÐ×÷Ó㬻ᱻϵͳËùºöÂÔ¡£¶ø UDP Socket Èç¹ûºô½ÐÁË
connect() º¯Ê½À´Ö¸¶¨¶Ô·½µÄλַ£¨Õâ¸ö connect ²¢²»»áÕæµÄºÍ¶Ô·½×öÁ¬½ÓµÄ¶¯
×÷£¬¶øÊǸæÖªÎÒÃDZ¾ÉíµÄϵͳ˵ÎÒÃÇÖ»ÏëÊÕ¡¢Ëͺη½µÄ×ÊÁÏ£©£¬ÄÇ÷áÒ²¿ÉÒÔÀû
Óàsend() ¼° recv() À´ËÍÊÕ×ÊÁÏ¡£

¡ò sendto()£º½«×ÊÁÏË͵½Ê¹ÓÃÕßÖ¸¶¨µÄÄ¿µÄµØ¡£
¸ñ  Ê½£º int PASCAL FAR sendto( SOCKET s, const char FAR *buf,
        int len, int flags, const struct sockaddr FAR *to, int
tolen );
²Î  Êý£º        s       Socket µÄʶ±ðÂë
        buf     ´æ·ÅÒª´«Ë͵Ä×ÊÁϵÄÔÝ´æÇø
        len     buf µÄ³¤¶È
        flags   ´Ëº¯Ê½±»ºô½ÐµÄ·½Ê½
        to      ×ÊÁÏÒªËÍ´ïµÄλַ
        tolen   to µÄ´óС
´«»ØÖµ£º        ³É¹¦ - ËͳöµÄ×ÊÁϳ¤¶È
        Ê§°Ü - SOCKET_ERROR (ºô½Ð WSAGetLastError() ¿ÉµÃÖªÔ­Òò)
˵Ã÷£º ´Ëº¯Ê½ÊÊÓÃ춠Datagram »ò Stream Socket À´´«ËÍ×ÊÁϵ½Ö¸¶¨µÄ
λַ¡£ ¶Ô Datagram Socket ÑÔ£¬ÈôÊÇ datagram µÄ´óС³¬¹ýÏÞÖÆ£¬Ôò½«²»»á
ËͳöÈκÎ×ÊÁÏ£¬²¢»á´«»Ø´íÎóÖµ¡£¶Ô Stream Socket ÑÔ£¬Æä×÷ÓÃÓë send() Ïà
ͬ£»²ÎÊý to ¼° tolen µÄÖµ½«±»ÏµÍ³ËùºöÂÔ¡£ ÈôÊÇ´«ËÍ (transport) ÏµÍ³ÄÚÖ®´¢
´æ¿Õ¼ä²»¹»´æ·ÅÕâЩҪ´«Ë͵Ä×ÊÁÏ£¬sendto() ½«»á±» block ×¡£¬Ö±µ½×ÊÁ϶¼±»
Ëͳö£»³ý·Ç¸Ã Socket ±»É趨Ϊ non-blocking Ä£Ê½¡£Ê¹ÓÃÕßÒàÐë×¢Òâ sendto()
º¯Ê½Ö´ÐÐÍê³É£¬²¢²»±íʾ×ÊÁÏÒѾ­³É¹¦µØË͵ֶԷ½ÁË£¬¶ø¿ÉÄÜÈÔÔÚϵͳµÄ output
buffer ÖС£ flags µÄÖµ¿ÉÉèΪ 0¡¢MSG_DONTROUTE ¼° MSG_OOB µÄ×éºÏ¡£
(²Î¼û WINSOCKµÚ1.1°æ51Ò³)

¡ò recvfrom()£º¶ÁÈ¡×ÊÁÏ£¬²¢´¢´æ×ÊÁÏÀ´Ô´µÄλַ¡£
¸ñ  Ê½£º int PASCAL FAR recvfrom( SOCKET s, char FAR *buf, int len,  int flags,
        struct socketaddr FAR *from, int FAR  *fromlen );
²Î  Êý£º        s       Socket µÄʶ±ðÂë
        buf     ´æ·Å½ÓÊÕµ½µÄ×ÊÁϵÄÔÝ´æÇø
        len     buf µÄ³¤¶È
        flags   ´Ëº¯Ê½±»ºô½ÐµÄ·½Ê½
        from    ×ÊÁÏÀ´Ô´µÄλַ
        fromlen from µÄ´óС
´«»ØÖµ£º        ³É¹¦ - ½ÓÊÕµ½µÄ×ÊÁϳ¤¶È (Èô¶Ô·½ Socket Òѹرգ¬ÔòΪ 0)
        Ê§°Ü - SOCKET_ERROR (ºô½Ð WSAGetLastError() ¿ÉµÃÖªÔ­Òò)
˵Ã÷£º  ´Ëº¯Ê½ÓÃÀ´¶ÁÈ¡×ÊÁϲ¢¼Ç¼×ÊÁÏÀ´Ô´µÄλַ¡£¶Ô Datagram Socket
£¨UDP£©ÑÔ£¬Ò»´Î¶ÁÈ¡Ò»¸ö Datagram£»¶Ô Stream Socket £¨TCP£©ÑÔ£¬Æä×÷ÓÃÓë
recv() Ïàͬ£¬²ÎÊý from ¼° fromlen µÄÖµ»á±»ÏµÍ³ºöÂÔ¡£Èç¹û  Socket Îª Blocking Ä£
ʽ£¬ÇÒÄ¿Ç° input buffer ÄÚûÓÐÈκÎ×ÊÁÏ£¬Ôò recvftom() ½« block µ½ÓÐÈκÎ×ÊÁϵ½
´ïΪֹ£»Èç¹ûΪ Non-Blocking Ä£Ê½£¬ÇÒ input buffer ÎÞÈκÎ×ÊÁÏ£¬Ôò»áÂíÉϻظ²´í
Îó¡£

¡¾FD_WRITE Ê¼þ¡¿

±ÊÕßÔÚÇ°Ãæ½éÉܹý FD_READ Ê¼þµÄ·¢Éúʱ»ú£¬ÏÖÔÚ¼ÌÐø½éÉÜ FD_WRITE
Õâ¸ö½ÏÒ×ʹÈË»ìÏýµÄʼþ£¬ÒòΪÕæµÄÓÐÏ൱¶àµÄÈ˶ԴËһʼþµÄ·¢Éú²»Ã÷ÁË¡£

ÓÉ×ÖÃæÉÏ¿´£¬FD_WRITE Ó¦¸ÃÊÇÒªÇóϵͳ֪ͨÎÒÃÇij¸ö Socket ÏÖÔÚÊÇ·ñ¿É
ÒÔºô½Ð send() »ò sendto() À´´«ËÍ×ÊÁÏ£¿´ð°¸¿ÉÒÔ˵¡¸ÊÇ¡¹£¬µ«ÊÇËüºÍ FD_READ
È´ÓÖÓв»Í¬µÄµØ·½¡£

ÔÚÇ°ÃæÎÒÃÇÖªµÀºô½ÐÒ»´Î recv() áᣬÈç¹û input buffer ÖÐÉÐÓÐ×ÊÁÏδ±»È¡³ö
µÄ»°£¬ÏµÍ³»áÔÙ֪ͨÎÒÃÇÒ»´Î FD_READ¡£ÄÇ÷áÈç¹ûÎÒÃǺô½ÐÒ»´Î send() áᣬ
ϵͳµÄ output buffer ÈÔÓпռä¿ÉдÈëµÄ»°£¬ËüÊÇ·ñ»áÔÙ֪ͨÎÒÃÇÒ»¸ö
FD_WRITE£¬½ÐÎÒÃǼÌÐø´«ËÍ×ÊÁÏÄØ£¿Õâ¸ö´ð°¸¾ÍÊÇ¡¸·ñ¶¨¡¹µÄÁË£¡ÏµÍ³²¢²»
»áÔÙ֪ͨÎÒÃÇÁË¡£

ϵͳ»á֪ͨÎÒÃÇ FD_WRITE Ê¼þµÄѶϢ£¬Ö»ÓÐÏÂÁм¸ÖÖÇé¿ö£º

£¨1£©ºô½Ð WSAAsyncSelect() À´É趨 FD_WRITE Ê¼þʱ£¬Socket ÒѾ­¿ÉÒÔ
´«ËÍ×ÊÁÏ£¨TCP scoket ÒѾ­ºÍ¶Ô·½Á¬½Ó³É¹¦ÁË£¬»ò UDP socket Òѽ¨Á¢Íê³É£©£¬
ÇÒÄ¿Ç° output buffer ÈÔÓпռä¿ÉдÈë×ÊÁÏ¡£
£¨2£©ºô½Ð WSAAsyncSelect() À´É趨 FD_WRITE Ê¼þʱ£¬Socket Éв»ÄÜ´«
ËÍ×ÊÁÏ£¬²»¹ýÒ»µ© Socket Óë¶Ô·½Á¬½Ó³É¹¦£¬ÂíÉϾͻáÊÕµ½ FD_WRITE µÄͨ
Öª¡£
£¨3£©ºô½Ð send() »ò sendto() ´«ËÍ×ÊÁÏʱ£¬ÏµÍ³¸æÖª´íÎó£¬ÇÒ´íÎóÂëΪ
10035 WSAEWOULDBLOCK £¨ºô½Ð WSAGetLastError() µÃÖªÕâÏî´íÎ󣩣¬Õâ
ʱ±íʾ output buffer ÒѾ­ÂúÁË£¬ÎÞ·¨ÔÙдÈëÈκÎ×ÊÁÏ£¨´Ëʱ¼´Áîºô½ÐÔÙ¶à´ÎµÄ
send() Ò²¶¼Ò»¶¨Ê§°Ü£©£»Ò»µ©ÏµÍ³½«²¿·Ý×ÊÁϳɹ¦Ë͵ֶԷ½£¬¿Õ³ö output buffer
áᣬ±ã»áËÍÒ»¸ö FD_WRITE ¸øʹÓÃÕߣ¬¸æÖª¿É¼ÌÐø´«ËÍ×ÊÁÏÁË¡£»»¾ä»°Ëµ£¬¶Á
ÕßÔÚºô½Ð send() ´«ËÍ×ÊÁÏʱ£¬Ö»Òª²»ÊÇ·µ»Ø´íÎó 10035 µÄ»°£¬±ã¿ÉÒ»Ö±¼ÌÐøºô
½Ð send() À´´«ËÍ×ÊÁÏ£»Ò»µ© send() »Ø·µ´íÎó 10035£¬ÄÇ÷á±ã²»ÒªÔÙºô½Ð send()
´«ËÍ×ÊÁÏ£¬¶øÐëµÈÊÕµ½ FD_WRITE áᣬÔÙ¼ÌÐø´«ËÍ×ÊÁÏ¡£

¡¾½áÓï¡¿

ÔÚÕâÒ»ÆÚµÄÎÄÕÂÖУ¬±ÊÕß½éÉÜÁ˸÷λÓйؠTCP Socket µÄ×ÊÁÏÊÕ¡¢ËÍ·½Ê½¼°
FD_READ¡¢FD_WRITE µÈʼþµÄ·¢Éúʱ»ú£»¶ÁÕßÃÇ×ÛºÏÇ°Ò»ÆÚµÄÎÄÕ£¬Ó¦¸Ã
ÒѾ­¿ÉÒÔ½¨Á¢³öÒ»¶ÔÖ÷´Ó¼Ü¹¹µÄ³Ìʽ£¬²¢ÀûÓàTCP Socket À´´«ËÍ×ÊÁÏÁË¡£

ÏÂÒ»ÆÚ£¬±ÊÕß½«¼ÌÐø½éÉÜÓйØÈçºÎ»ñÈ¡Íø·×ÊѶµÄº¯Ê½£¬Èç
gethostname()¡¢getsockname()¡¢getpeername()£¬ÒÔ¼°Í¬²½Óë·Çͬ²½µÄÍø·×ÊÁÏ¿â
ߢȡº¯Ê½ getXbyY()¡¢WSAAsyncGetXByY()¡£

±¾ÎÄÖÐËùÌáµ½µÄ WinKing ÊÔÓðæ¿É×Ô SEEDNET Ì¨±±Ö÷»ú tpts1.seed.net.tw
£¨139.175.1.10£©µÄ UPLOAD/WINKING Ä¿Â¼ÖÐÈ¡µÃ£¬µµÃûΪ wkdemo.exe£»
WinKing Ìṩ Ethernet ¼° PPP Á¬Ïß¹¦ÄÜ£¬ÊÊÓÃì¶Ò»°ã Ethernet Íø·£¬Òà¿ÉÓÃÀ´
ÒԵ绰¡¢Êý¾Ý»úÁ¬ÉÏ SEEDNET µÄ PPP ËÅ·þÖ÷»ú£»¡õÀý demoserv¡¢democlnt£¬
ÒÔ¼°Ò»Ð©±ÊÕßËùдµÄ Winsock ³Ìʽ£¨º¬Ô­Ê¼³ÌʽÂ룩Ôò´æ·ÅÔÚ
UPLOAD/WINKING/JNLIN Ä¿Â¼Ï£»ÓÐÐËȤµÄ¶ÁÕß¿É×ÔÐÐÓàanonymous ftp ·½Ê½
È¡µÃ¡£

--
¡ù À´Ô´:£®°×ɽºÚË® bbs.neu.edu.cn£®[FROM: beaver]

--
¡ù À´Ô´:¡¤¹þ¶û±õ×϶¡ÏãÕ¾ bbs1.hit.edu.cn¡¤[FROM: bbs@conger.neu.edu.c] 
[°Ù±¦Ïä] [·µ»ØÊ×Ò³] [Éϼ¶Ä¿Â¼] [¸ùĿ¼] [·µ»Ø¶¥²¿] [Ë¢ÐÂ] [·µ»Ø]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
Ò³ÃæÖ´ÐÐʱ¼ä£º220.929ºÁÃë