锘??xml version="1.0" encoding="utf-8" standalone="yes"?> 鈼咺/O鎿嶄綔鍑芥暟錛氫富瑕佺敤浜庤幏鍙栦笌濂楁帴瀛楃浉鍏崇殑鎿嶄綔鍙傛暟銆? Hevent涓轟簨浠跺璞?br> lpEvent涓轟簨浠跺彞鏌勬暟緇勭殑鎸囬拡 e銆佸垽鏂綉緇滀簨浠剁被鍨嬶細(xì) s涓哄鎺ュ瓧 f銆佸叧闂簨浠跺璞″彞鏌勶細(xì) 璋冪敤鎴愬姛榪斿洖TRUE錛屽惁鍒欒繑鍥濬ALSE銆?br> 鈼嗗厛鐪嬪畾涔夛細(xì) 鈼哠ocket鏈変簲縐嶄笉鍚岀殑綾誨瀷錛?/p>
1銆佹祦寮忓鎺ュ瓧(stream socket) #define SOCK_STREAM 1 嫻佸紡濂楁帴瀛楁彁渚涗簡(jiǎn)鍙屽悜銆佹湁搴忕殑銆佹棤閲嶅鐨勪互鍙?qiáng)鏃犺褰曡竟鐣岀殑鏁版嵁娴佹湇鍔″Q岄傚悎澶勭悊澶ч噺鏁版嵁銆傚畠鏄潰鍚戣仈緇撶殑錛屽繀欏誨緩绔嬫暟鎹紶杈撻摼璺紝鍚屾椂榪樺繀欏誨浼犺緭鐨勬暟鎹繘琛岄獙璇侊紝紜繚鏁版嵁鐨勫噯紜с傚洜姝わ紝緋葷粺寮閿杈冨ぇ銆?/p>
2銆?鏁版嵁鎶ュ鎺ュ瓧(datagram socket) 瀹氫箟錛?/p>
#define SOCK_DGRAM 2 鏁版嵁鎶ュ鎺ュ瓧涔熸敮鎸佸弻鍚戠殑鏁版嵁?huà)箒锛屼絾涓嶄繚璇佷紶杈撴暟鎹殑鍑喖嫯鎬э紝浣嗕繚鐣欎簡(jiǎn)璁板綍杈圭晫銆傜敱浜庢暟鎹姤濂楁帴瀛楁槸鏃犺仈鎺ョ殑錛屼緥濡傚箍鎾椂鐨勮仈鎺ワ紝鎵浠ュ茍涓嶄繚璇佹帴鏀剁鏄惁姝e湪渚﹀惉銆傛暟鎹姤濂楁帴瀛椾紶杈撴晥鐜囨瘮杈冮珮銆?/p>
3銆佸師濮嬪鎺ュ瓧(raw-protocol interface) 瀹氫箟錛?/p>
#define SOCK_RAW 3 鍘熷濂楁帴瀛椾繚瀛樹(shù)簡(jiǎn)鏁版嵁鍖呬腑鐨勫畬鏁碔P澶達(dá)紝鍓嶉潰涓ょ濂楁帴瀛楀彧鑳芥敹鍒扮敤鎴鋒暟鎹傚洜姝ゅ彲浠ラ氳繃鍘熷濂楁帴瀛楀鏁版嵁榪涜鍒嗘瀽銆?br>鍏跺畠涓ょ濂楁帴瀛椾笉甯哥敤錛岃繖閲屽氨涓嶄粙緇嶄簡(jiǎn)銆?/p>
鈼哠ocket寮鍙戞墍蹇呴』闇瑕佺殑鏂囦歡(浠inSock V2.0涓轟緥)錛?/p>
澶存枃浠訛細(xì)Winsock2.h 搴撴枃浠訛細(xì)WS2_32.LIB 鍔ㄦ佸簱錛歐32_32.DLL 涓浜涢噸瑕佺殑瀹氫箟 1銆佹暟鎹被鍨嬬殑鍩烘湰瀹氫箟錛氳繖涓ぇ瀹朵竴鐪嬪氨鎳傘?/p>
typedef unsigned char u_char; 鈼?鏃х殑緗戠粶鍦板潃緇撴瀯鐨勫畾涔夛紝涓轟竴涓?瀛楄妭鐨勮仈鍚堬細(xì) struct in_addr { 鈼?鏂扮殑緗戠粶鍦板潃緇撴瀯鐨勫畾涔夛細(xì) #define INADDR_LOOPBACK 0x7f0000013銆?濂楁帴瀛楀湴鍧緇撴瀯 (1)銆乻ockaddr緇撴瀯錛?/p>
struct sockaddr { (2)銆乻ockaddr_in緇撴瀯 struct sockaddr_in { 鈼?灝嗗父鐢ㄧ殑鐢ㄧ偣鍒嗗紑鐨処P鍦板潃杞崲涓簎nsigned long綾誨瀷鐨処P鍦板潃鐨勫嚱鏁幫細(xì) unsigned long inet_addr(const char FAR * cp )鐢ㄦ硶錛?/p>
unsigned long addr=inet_addr("192.1.8.84")鈼?濡傛灉灝唖in_addr璁劇疆涓篒NADDR_ANY錛屽垯琛ㄧず鎵鏈夌殑IP鍦板潃錛屼篃鍗蟲(chóng)墍鏈夌殑璁$畻鏈恒?/p>
#define INADDR_ANY (u_long)0x000000004銆?涓繪満鍦板潃錛?/p>
鍏堢湅瀹氫箟錛?/p>
struct hostent { 5銆?甯歌TCP/IP鍗忚鐨勫畾涔夛細(xì) #define IPPROTO_IP 0 濂楁帴瀛楃殑灞炴?/p>
涓轟簡(jiǎn)鐏墊椿浣跨敤濂楁帴瀛楋紝鎴戜滑鍙互瀵瑰畠鐨勫睘鎬ц繘琛岃瀹氥?/p>
1銆?灞炴у唴瀹癸細(xì) //鍏佽璋冭瘯杈撳嚭 int getsockopt(SOCKET s, int level, int optname, char FAR * optval, int FAR * optlen)s涓烘璇誨彇灞炴х殑濂楁帴瀛椼俵evel涓哄鎺ュ瓧閫夐」鐨勭駭鍒紝澶у鏁版槸鐗瑰畾鍗忚鍜屽鎺ュ瓧涓撴湁鐨勩傚IP鍗忚搴斾負(fù) IPPROTO_IP銆?/p>
optname涓鴻鍙栭夐」鐨勫悕縐?br>optval涓哄瓨鏀鵑夐」鍊肩殑緙撳啿鍖烘寚閽堛?br>optlen涓虹紦鍐插尯鐨勯暱搴︾敤娉曪細(xì) int ttl=0; //璇誨彇TTL鍊?br>int rc = getsockopt( s, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl)); int setsockopt(SOCKET s,int level, int optname,const char FAR * optval, int optlen)s涓烘璁劇疆灞炴х殑濂楁帴瀛椼?br>level涓哄鎺ュ瓧閫夐」鐨勭駭鍒紝鐢ㄦ硶鍚屼笂銆?br>optname涓鴻緗夐」鐨勫悕縐?br>optval涓哄瓨鏀鵑夐」鍊肩殑緙撳啿鍖烘寚閽堛?br>optlen涓虹紦鍐插尯鐨勯暱搴?/p>
鐢ㄦ硶錛?/p>
int ttl=32; //璁劇疆TTL鍊?br>int rc = setsockopt( s, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl)); 濂楁帴瀛楃殑浣跨敤姝ラ 1銆佸惎鍔╓insock錛氬Winsock DLL榪涜鍒濆鍖栵紝鍗忓晢Winsock鐨勭増鏈敮鎸佸茍鍒嗛厤蹇呰鐨?br>璧勬簮銆傦紙鏈嶅姟鍣ㄧ鍜屽鎴風(fēng)錛?/p>
int WSAStartup( WORD wVersionRequested, LPWSADATA lpWSAData ) wVersionRequested涓烘墦綆楀姞杞絎insock鐨勭増鏈紝涓鑸涓嬭緗細(xì) LPWSADATA涓哄垵濮嬪寲Socket鍚庡姞杞界殑鐗堟湰鐨勪俊鎭?瀹氫箟濡備笅錛?br>typedef struct WSAData { wVersion錛?琛ㄧず鍔犺澆鐗堟湰涓?.0銆?br>wHighVersion錛?14琛ㄧず褰撳墠緋葷粺鏀寔socket鏈楂樼増鏈負(fù)2.2銆?br>szDescription="WinSock 2.0" WORD wVersion=MAKEWORD(2,0); SOCKET socket( int af, int type, int protocol ); SOCKET sock=socket(AF_INET,SOCK_STREAM,IPPROTO_IP); int bind( SOCKET s, const struct sockaddr FAR * name, int namelen ) sockaddr_in addr; int listen(SOCKET s, int backlog )s涓轟竴涓凡緇戝畾浣嗘湭鑱旀帴鐨勫鎺ュ瓧銆?br>backlog涓烘寚瀹氭鍦ㄧ瓑寰呰仈鎺ョ殑鏈澶ч槦鍒楅暱搴︼紝榪欎釜鍙傛暟闈炲父閲嶈錛屽洜涓烘湇鍔″櫒涓鑸彲 int nResult=listen(s,5) //鏈澶?涓繛鎺?br>if(nResult==SOCKET_ERROR) SOCKET accept( SOCKET s, struct sockaddr FAR * addr, int FAR * addrlen )s涓哄浜庣洃鍚ā寮忕殑濂楁帴瀛椼?br>sockaddr涓烘帴鏀舵垚鍔熷悗榪斿洖瀹㈡埛绔殑緗戠粶鍦板潃銆?br>addrlen涓虹綉緇滃湴鍧鐨勯暱搴︺?/p>
鐢ㄦ硶錛?/p>
sockaddr_in addr; int connect(SOCKET s, const struct sockaddr FAR * name, int namelen )s涓烘榪炵粨鐨勫凡鍒涘緩鐨勫鎺ュ瓧銆?br>name涓烘榪炵粨鐨剆ocket鍦板潃銆?br>namelen涓簊ocket鍦板潃鐨勭粨鏋勭殑闀垮害銆?/p>
鐢ㄦ硶錛?/p>
sockaddr_in addr; int send(SOCKET s, const char FAR * buf, int len, int flags )s涓烘湇鍔″櫒绔洃鍚殑濂楁帴瀛椼?br>buf涓烘鍙戦佹暟鎹紦鍐插尯鐨勬寚閽堛?br>len涓哄彂閫佹暟鎹紦鍐插尯鐨勯暱搴︺?br>flags涓烘暟鎹彂閫佹爣璁般?br>榪斿洖鍊間負(fù)鍙戦佹暟鎹殑瀛楃鏁般?/p>
鈼嗚繖閲岃涓涓嬭繖涓彂閫佹爣璁幫紝涓嬮潰8涓璁虹殑鎺ユ敹鏍囪涔熶竴鏍鳳細(xì) flag鍙栧煎繀欏諱負(fù)0鎴栬呭涓嬪畾涔夌殑緇勫悎錛?琛ㄧず娌℃湁鐗規(guī)畩琛屼負(fù)銆?/p>
#define MSG_OOB 0x1 /* process out-of-band data */ 鐢ㄦ硶錛?/p>
char buf[]="xiaojin"; int recv( SOCKET s, char FAR * buf, int len, int flags )s涓哄噯澶囨帴鏀舵暟鎹殑濂楁帴瀛椼?br>buf涓哄噯澶囨帴鏀舵暟鎹殑緙撳啿鍖恒?br>len涓哄噯澶囨帴鏀舵暟鎹紦鍐插尯鐨勫ぇ灝忋?br>flags涓烘暟鎹帴鏀舵爣璁般?br>榪斿洖鍊間負(fù)鎺ユ敹鐨勬暟鎹殑瀛楃鏁般?/p>
鐢ㄦ硶錛?/p>
char mess[1000]; int shutdown(SOCKET s, int how)s涓烘涓柇榪炴帴鐨勫鎺ュ瓧銆?br>How涓烘弿榪扮姝㈠摢浜涙搷浣滐紝鍙栧間負(fù)錛歋D_RECEIVE銆丼D_SEND銆丼D_BOTH銆?/p>
#define SD_RECEIVE 0x00 int nResult= shutdown(s,SD_BOTH); int closesocket( SOCKET s )s涓烘鍏抽棴鐨勫鎺ュ瓧銆?/p>
鐢ㄦ硶錛?/p>
int nResult=closesocket(s); 鏈枃鏉ヨ嚜CSDN鍗氬錛岃漿杞借鏍囨槑鍑哄錛?a >http://blog.csdn.net/coffeemay/archive/2006/08/05/1023149.aspx
]]>
2銆佸皢涓繪満鐨剈nsigned long鍊艱漿鎹負(fù)緗戠粶瀛楄妭欏哄簭(32浣?錛氫負(fù)浠涔堣榪欐牱鍋氬憿錛熷洜涓轟笉鍚岀殑璁$畻鏈轟嬌鐢ㄤ笉鍚岀殑瀛楄妭欏哄簭瀛樺偍鏁版嵁銆傚洜姝や換浣曚粠Winsock鍑芥暟瀵笽P鍦板潃鍜岀鍙e彿鐨勫紩鐢ㄥ拰浼犵粰Winsock鍑芥暟鐨処P鍦板潃鍜岀鍙e彿鍧囨椂鎸夌収緗戠粶欏哄簭緇勭粐鐨勩?br>
u_long htonl(u_long hostlong);
涓句緥錛歨tonl(0)=0
htonl(80)= 1342177280
3銆佸皢unsigned long鏁頒粠緗戠粶瀛楄妭欏哄簭杞崲浣嶄富鏈哄瓧鑺傞『搴忥紝鏄笂闈㈠嚱鏁扮殑閫嗗嚱鏁般?
u_long ntohl(u_long netlong);
涓句緥錛歯tohl(0)=0
ntohl(1342177280)= 80
4銆佸皢涓繪満鐨剈nsigned short鍊艱漿鎹負(fù)緗戠粶瀛楄妭欏哄簭(16浣?錛氬師鍥犲悓2錛?
u_short htons(u_short hostshort);
涓句緥錛歨tonl(0)=0
htonl(80)= 20480
5銆佸皢unsigned short鏁頒粠緗戠粶瀛楄妭欏哄簭杞崲浣嶄富鏈哄瓧鑺傞『搴忥紝鏄笂闈㈠嚱鏁扮殑閫嗗嚱鏁般?
u_short ntohs(u_short netshort);
涓句緥錛歯tohs(0)=0
ntohsl(20480)= 80
6銆佸皢鐢ㄧ偣鍒嗗壊鐨処P鍦板潃杞崲浣嶄竴涓猧n_addr緇撴瀯鐨勫湴鍧錛岃繖涓粨鏋勭殑瀹氫箟瑙佺瑪璁?涓)錛屽疄闄呬笂灝辨槸涓涓猽nsigned long鍊箋傝綆楁満鍐呴儴澶勭悊IP鍦板潃鍙槸涓嶈璇嗗192.1.8.84涔嬬被鐨勬暟鎹?
unsigned long inet_addr( const char FAR * cp );
涓句緥錛歩net_addr("192.1.8.84")=1409810880
inet_addr("127.0.0.1")= 16777343
濡傛灉鍙戠敓閿欒錛屽嚱鏁拌繑鍥濱NADDR_NONE鍊箋?br>
7銆佸皢緗戠粶鍦板潃杞崲浣嶇敤鐐瑰垎鍓茬殑IP鍦板潃錛屾槸涓婇潰鍑芥暟鐨勯嗗嚱鏁般?
char FAR * inet_ntoa( struct in_addr in );
涓句緥錛歝har * ipaddr=NULL;
char addr[20];
in_addr inaddr;
inaddr. s_addr=16777343;
ipaddr= inet_ntoa(inaddr);
strcpy(addr,ipaddr);
榪欐牱addr鐨勫煎氨鍙樹(shù)負(fù)127.0.0.1銆?br>娉ㄦ剰鎰忎笉瑕佷慨鏀硅繑鍥炲兼垨鑰呰繘琛岄噴鏀懼姩浣溿傚鏋滃嚱鏁板け璐ュ氨浼?xì)杩斿洖NULL鍊箋?br>
8銆佽幏鍙栧鎺ュ瓧鐨勬湰鍦板湴鍧緇撴瀯錛?
int getsockname(SOCKET s, struct sockaddr FAR * name, int FAR * namelen );
s涓哄鎺ュ瓧
name涓哄嚱鏁拌皟鐢ㄥ悗鑾峰緱鐨勫湴鍧鍊?
namelen涓虹紦鍐插尯鐨勫ぇ灝忋?
9銆佽幏鍙栦笌濂楁帴瀛楃浉榪炵殑绔湴鍧緇撴瀯錛?br>
int getpeername(SOCKET s, struct sockaddr FAR * name, int FAR * namelen );
s涓哄鎺ュ瓧
name涓哄嚱鏁拌皟鐢ㄥ悗鑾峰緱鐨勭鍦板潃鍊?
namelen涓虹紦鍐插尯鐨勫ぇ灝忋?
10銆佽幏鍙栬綆楁満鍚嶏細(xì)
int gethostname( char FAR * name, int namelen );
name鏄瓨鏀捐綆楁満鍚嶇殑緙撳啿鍖?
namelen鏄紦鍐插尯鐨勫ぇ灝?
鐢ㄦ硶錛?
char szName[255];
memset(szName,0,255);
if(gethostname(szName,255)==SOCKET_ERROR)
{
//閿欒澶勭悊
}
榪斿洖鍊間負(fù)錛歴zNmae="xiaojin"
11銆佹牴鎹綆楁満鍚嶈幏鍙栦富鏈哄湴鍧錛?
struct hostent FAR * gethostbyname( const char FAR * name );
name涓鴻綆楁満鍚嶃?
鐢ㄦ硶錛?
hostent * host;
char* ip;
host= gethostbyname("xiaojin");
if(host->h_addr_list[0])
{
struct in_addr addr;
memmove(&addr, host->h_addr_list[0]錛?);
//鑾峰緱鏍囧噯IP鍦板潃
ip=inet_ ntoa (addr);
}
榪斿洖鍊間負(fù)錛歨ostent->h_name="xiaojin"
hostent->h_addrtype=2 //AF_INET
hostent->length=4
ip="127.0.0.1"
Winsock 鐨処/O鎿嶄綔錛?/strong>
1銆?涓ょI/O妯″紡
涓轟簡(jiǎn)瑙e喅榪欎釜闂錛屾彁鍑轟簡(jiǎn)榪涜I/O鎿嶄綔鐨勪竴浜汭/O妯″瀷,涓嬮潰浠嬬粛鏈甯歌鐨勪笁縐嶏細(xì)
2銆乻elect妯″瀷錛?br>
銆銆閫氳繃璋冪敤select鍑芥暟鍙互紜畾涓涓垨澶氫釜濂楁帴瀛楃殑鐘舵侊紝鍒ゆ柇濂楁帴瀛椾笂鏄惁鏈夋暟鎹紝鎴?br>鑰呰兘鍚﹀悜涓涓鎺ュ瓧鍐欏叆鏁版嵁銆?
int select( int nfds, fd_set FAR * readfds, fd_set FAR * writefds,
fd_set FAR *exceptfds, const struct timeval FAR * timeout );
鈼嗗厛鏉ョ湅鐪嬫秹鍙?qiáng)鍒扮殑缁撴瀯鐨勫畾涔夊Q?br>a銆?d_set緇撴瀯錛?br>
#define FD_SETSIZE 64?
typedef struct fd_set {
u_int fd_count; /* how many are SET? */
SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */
} fd_set;
fd_count涓哄凡璁懼畾socket鐨勬暟閲?br>fd_array涓簊ocket鍒楄〃錛孎D_SETSIZE涓烘渶澶ocket鏁伴噺錛屽緩璁笉灝忎簬64銆傝繖鏄井杞緩
璁殑銆?br>
B銆乼imeval緇撴瀯錛?
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
tv_sec涓烘椂闂寸殑縐掑箋?br>tv_usec涓烘椂闂寸殑姣鍊箋?br>榪欎釜緇撴瀯涓昏鏄緗畇elect()鍑芥暟鐨勭瓑寰呭鹼紝濡傛灉灝嗚緇撴瀯璁劇疆涓?0,0)錛屽垯select()鍑芥暟
浼?xì)绔嬪崒櫩斿洖銆?br>
鈼嗗啀鏉ョ湅鐪媠elect鍑芥暟鍚勫弬鏁扮殑浣滅敤錛?
readfds銆亀ritefds銆乪xceptfds涓変釜鍙橀噺鑷沖皯鏈変竴涓笉涓虹┖錛屽悓鏃惰繖涓笉涓虹┖鐨勫鎺ュ瓧緇?br>縐嶈嚦灝戞湁涓涓猻ocket錛岄亾鐞嗗緢綆鍗曪紝鍚﹀垯瑕乻elect騫蹭粈涔堝憿銆?涓句緥錛氭祴璇曚竴涓鎺ュ瓧鏄惁鍙錛?
fd_set fdread;
//FD_ZERO瀹氫箟
// #define FD_ZERO(set) (((fd_set FAR *)(set))->fd_count=0)
FD_ZERO(&fdread);
FD_SET(s,&fdread)錛?//鍔犲叆濂楁帴瀛楋紝璇︾粏瀹氫箟璇風(fēng)湅winsock2.h
if(select(0,%fdread,NULL,NULL,NULL)>0
{
//鎴愬姛
if(FD_ISSET(s,&fread) //鏄惁瀛樺湪fread涓紝璇︾粏瀹氫箟璇風(fēng)湅winsock2.h
{
//鏄彲璇葷殑
}
}
int ioctlsocket(SOCKET s, long cmd, u_long FAR * argp );
s涓篒/O鎿嶄綔鐨勫鎺ュ瓧銆?br>cmd涓哄濂楁帴瀛楃殑鎿嶄綔鍛戒護(hù)銆?br>argp涓哄懡浠ゆ墍甯﹀弬鏁扮殑鎸囬拡銆?br>
甯歌鐨勫懡浠わ細(xì)
//紜畾濂楁帴瀛楄嚜鍔ㄨ鍏ョ殑鏁版嵁閲?
#define FIONREAD _IOR(''''f'''', 127, u_long) /* get # bytes to read */
//鍏佽鎴栫姝㈠鎺ュ瓧鐨勯潪闃誨妯″紡錛屽厑璁鎬負(fù)闈?錛岀姝負(fù)0
#define FIONBIO _IOW(''''f'''', 126, u_long) /* set/clear non-blocking i/o */
//紜畾鏄惁鎵鏈夊甫澶栨暟鎹兘宸茶璇誨叆
#define SIOCATMARK _IOR(''''s'''', 7, u_long) /* at oob mark? */
3銆乄SAAsynSelect妯″瀷錛?br>WSAAsynSelect妯″瀷涔熸槸涓涓父鐢ㄧ殑寮傛I/O妯″瀷銆傚簲鐢ㄧ▼搴忓彲浠ュ湪涓涓鎺ュ瓧涓婃帴鏀朵互
WINDOWS娑堟伅涓哄熀紜鐨勭綉緇滀簨浠墮氱煡銆傝妯″瀷鐨勫疄鐜版柟娉曟槸閫氳繃璋冪敤WSAAsynSelect鍑?br>鏁?鑷姩灝嗗鎺ュ瓧璁劇疆涓洪潪闃誨妯″紡錛屽茍鍚慦INDOWS娉ㄥ唽涓涓垨澶氫釜緗戠粶鏃墮棿錛屽茍鎻愪緵涓
涓氱煡鏃朵嬌鐢ㄧ殑紿楀彛鍙ユ焺銆傚綋娉ㄥ唽鐨勪簨浠跺彂鐢熸椂錛屽搴旂殑紿楀彛灝嗘敹鍒頒竴涓熀浜庢秷鎭殑閫氱煡銆?br>
int WSAAsyncSelect( SOCKET s, HWND hWnd, u_int wMsg, long lEvent);
s涓洪渶瑕佷簨浠墮氱煡鐨勫鎺ュ瓧
hWnd涓烘帴鏀舵秷鎭殑紿楀彛鍙ユ焺
wMsg涓鴻鎺ユ敹鐨勬秷鎭?br>lEvent涓烘帺鐮侊紝鎸囧畾搴旂敤紼嬪簭鎰熷叴瓚g殑緗戠粶浜嬩歡緇勫悎錛屼富瑕佸涓嬶細(xì)
#define FD_READ_BIT 0
#define FD_READ (1 << FD_READ_BIT)
#define FD_WRITE_BIT 1
#define FD_WRITE (1 << FD_WRITE_BIT)
#define FD_OOB_BIT 2
#define FD_OOB (1 << FD_OOB_BIT)
#define FD_ACCEPT_BIT 3
#define FD_ACCEPT (1 << FD_ACCEPT_BIT)
#define FD_CONNECT_BIT 4
#define FD_CONNECT (1 << FD_CONNECT_BIT)
#define FD_CLOSE_BIT 5
#define FD_CLOSE (1 << FD_CLOSE_BIT)
鐢ㄦ硶錛氳鎺ユ敹璇誨啓閫氱煡錛?
int nResult= WSAAsyncSelect(s,hWnd,wMsg,FD_READ|FD_WRITE)錛?
if(nResult==SOCKET_ERROR)
{
//閿欒澶勭悊
}
鍙栨秷閫氱煡錛?br>
int nResult= WSAAsyncSelect(s,hWnd,0錛?)錛?
褰撳簲鐢ㄧ▼搴忕獥鍙Wnd鏀跺埌娑堟伅鏃訛紝wMsg.wParam鍙傛暟鏍囪瘑浜?jiǎn)濂楁帴瀛楀Q宭Param鐨勪綆瀛楁爣鏄?br>浜?jiǎn)缃懢l滀簨浠訛紝楂樺瓧鍒欏寘鍚敊璇唬鐮併?br>
4銆乄SAEventSelect妯″瀷
WSAEventSelect妯″瀷綾諱技WSAAsynSelect妯″瀷錛屼絾鏈涓昏鐨勫尯鍒槸緗戠粶浜嬩歡鍙戠敓鏃朵細(xì)琚彂
閫佸埌涓涓簨浠跺璞″彞鏌勶紝鑰屼笉鏄彂閫佸埌涓涓獥鍙c?br>
浣跨敤姝ラ濡備笅錛?br>a銆?鍒涘緩浜嬩歡瀵硅薄鏉ユ帴鏀剁綉緇滀簨浠訛細(xì)
#define WSAEVENT HANDLE
#define LPWSAEVENT LPHANDLE
WSAEVENT WSACreateEvent( void );
璇ュ嚱鏁扮殑榪斿洖鍊間負(fù)涓涓簨浠跺璞″彞鏌勶紝瀹冨叿鏈変袱縐嶅伐浣滅姸鎬侊細(xì)宸蹭紶淇?signaled)鍜屾湭浼犱俊
(nonsignaled)浠ュ強(qiáng)涓ょ宸ヤ綔妯″紡錛氫漢宸ラ噸璁?manual reset)鍜岃嚜鍔ㄩ噸璁?auto reset)銆傞粯璁ゆ湭
鏈紶淇$殑宸ヤ綔鐘舵佸拰浜哄伐閲嶈妯″紡銆?br>
b銆佸皢浜嬩歡瀵硅薄涓庡鎺ュ瓧鍏寵仈錛屽悓鏃舵敞鍐屼簨浠訛紝浣夸簨浠跺璞$殑宸ヤ綔鐘舵佷粠鏈紶淇¤漿鍙樻湭
宸蹭紶淇°?br>
int WSAEventSelect( SOCKET s,WSAEVENT hEventObject,long lNetworkEvents );
s涓哄鎺ュ瓧
hEventObject涓哄垰鎵嶅垱寤虹殑浜嬩歡瀵硅薄鍙ユ焺
lNetworkEvents涓烘帺鐮侊紝瀹氫箟濡備笂闈㈡墍榪?br>
c銆両/O澶勭悊鍚庯紝璁劇疆浜嬩歡瀵硅薄涓烘湭浼犱俊
BOOL WSAResetEvent( WSAEVENT hEvent );
鎴愬姛榪斿洖TRUE錛屽け璐ヨ繑鍥濬ALSE銆?br>
d銆佺瓑寰呯綉緇滀簨浠舵潵瑙﹀彂浜嬩歡鍙ユ焺鐨勫伐浣滅姸鎬侊細(xì)DWORD WSAWaitForMultipleEvents( DWORD cEvents,
const WSAEVENT FAR * lphEvents, BOOL fWaitAll,
DWORD dwTimeout, BOOL fAlertable );
cEvent涓轟負(fù)浜嬩歡鍙ユ焺鐨勬暟鐩紝鍏舵渶澶у間負(fù)WSA_MAXIMUM_WAIT_EVENTS
fWaitAll鎸囧畾絳夊緟綾誨瀷錛歍RUE錛氬綋lphEvent鏁扮粍閲嶆墍鏈変簨浠跺璞″悓鏃舵湁淇″彿鏃惰繑鍥烇紱
FALSE錛氫換涓浜嬩歡鏈変俊鍙峰氨榪斿洖銆?br>dwTimeout涓虹瓑寰呰秴鏃訛紙姣錛?br>fAlertable涓烘寚瀹氬嚱鏁拌繑鍥炴椂鏄惁鎵ц瀹屾垚渚嬬▼
瀵逛簨浠舵暟緇勪腑鐨勪簨浠惰繘琛屽紩鐢ㄦ椂錛屽簲璇ョ敤WSAWaitForMultipleEvents鐨勮繑鍥炲鹼紝鍑忓幓
棰勫0鏄庡糤SA_WAIT_EVENT_0錛屽緱鍒板叿浣撶殑寮曠敤鍊箋備緥濡傦細(xì)nIndex=WSAWaitForMultipleEvents(…);
MyEvent=EventArray[Index- WSA_WAIT_EVENT_0];
int WSAEnumNetworkEvents( SOCKET s,
WSAEVENT hEventObject, LPWSANETWORKEVENTS lpNetworkEvents );
hEventObject涓洪渶瑕侀噸璁劇殑浜嬩歡瀵硅薄
lpNetworkEvents涓鴻褰曠綉緇滀簨浠跺拰閿欒浠g爜錛屽叾緇撴瀯瀹氫箟濡備笅錛?/p>
typedef struct _WSANETWORKEVENTS {
long lNetworkEvents;
int iErrorCode[FD_MAX_EVENTS];
} WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;
BOOL WSACloseEvent(WSAEVENT hEvent);
]]>
typedef unsigned int u_int;
typedef u_int SOCKET;鈼哠ocket鐩稿綋浜庤繘琛岀綉緇滈氫俊涓ょ鐨勬彃搴э紝鍙瀵規(guī)柟鐨凷ocket鍜岃嚜宸辯殑Socket鏈夐氫俊鑱旀帴錛屽弻鏂瑰氨鍙互鍙戦佸拰鎺ユ敹鏁版嵁浜?jiǎn)銆傚叾瀹氫箟綾諱技浜庢枃浠跺彞鏌勭殑瀹氫箟銆?/p>
瀹氫箟錛?/p>
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;2銆?緗戠粶鍦板潃鐨勬暟鎹粨鏋勶紝鏈変竴涓佺殑鍜屼竴涓柊鐨勭殑錛岃澶у鐣欐剰錛屽鏋滄兂鐭ラ亾涓轟粈涔堬紝
璇峰彂閭歡緇橞ill Gate銆傚叾瀹炲氨鏄綆楁満鐨処P鍦板潃錛屼笉榪囦竴鑸笉鐢ㄧ敤鐐瑰垎寮鐨処P鍦?br>鍧錛屽綋鐒朵篃鎻愪緵涓浜涜漿鎹㈠嚱鏁般?/p>
union {
struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { u_short s_w1,s_w2; } S_un_w;
u_long S_addr;
} S_un;
#define s_addr S_un.S_addr /* can be used for most tcp & ip code */
//涓嬮潰鍑犺鐪佺暐,鍙嶆娌′粈涔堢敤澶勩?br>};鍏跺疄瀹屽叏涓嶇敤榪欎箞楹葷儲(chǔ)錛岃鐪嬩笅闈?
闈炲父綆鍗曪紝灝辨槸涓涓棤絎﹀彿闀挎暣鏁?unsigned long銆備婦涓緥瀛愶細(xì)IP鍦板潃涓?27.0.0.1鐨勭綉緇滃湴鍧鏄粈涔堝憿錛熻鐪嬪畾涔夛細(xì)
u_short sa_family; /* address family */
char sa_data[14]; /* up to 14 bytes of direct address */
};sa_family涓虹綉緇滃湴鍧綾誨瀷錛屼竴鑸負(fù)AF_INET錛岃〃紺鴻socket鍦↖nternet鍩熶腑榪涜閫氫俊錛岃鍦板潃緇撴瀯闅忛夋嫨鐨勫崗璁殑涓嶅悓鑰屽彉鍖栵紝鍥犳涓鑸儏鍐典笅鍙︿竴涓笌璇ュ湴鍧緇撴瀯澶у皬鐩稿悓鐨剆ockaddr_in緇撴瀯鏇翠負(fù)甯哥敤錛宻ockaddr_in緇撴瀯鐢ㄦ潵鏍囪瘑TCP/IP鍗忚涓嬬殑鍦板潃銆傛崲鍙ヨ瘽璇達(dá)紝榪欎釜緇撴瀯鏄氱敤socket鍦板潃緇撴瀯錛岃屼笅闈㈢殑sockaddr_in鏄笓闂ㄩ拡瀵笽nternet鍩熺殑socket鍦板潃緇撴瀯銆?/p>
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};sin _family涓虹綉緇滃湴鍧綾誨瀷錛屽繀欏昏瀹氫負(fù)AF_INET銆俿in_port涓烘湇鍔$鍙o紝娉ㄦ剰涓嶈浣跨敤宸插浐瀹氱殑鏈嶅姟绔彛錛屽HTTP鐨勭鍙?0絳夈傚鏋滅鍙h緗負(fù)0錛屽垯緋葷粺浼?xì)鑷姩鍒嗛厤涓涓敮涓绔彛銆俿in_addr涓轟竴涓猽nsigned long鐨処P鍦板潃銆俿in_zero涓哄~鍏呭瓧孌碉紝綰補(bǔ)鐢ㄦ潵淇濊瘉緇撴瀯鐨勫ぇ灝忋?/p>
char FAR * h_name; /* official name of host */
char FAR * FAR * h_aliases; /* alias list */
short h_addrtype; /* host address type */
short h_length; /* length of address */
char FAR * FAR * h_addr_list; /* list of addresses */
#define h_addr h_addr_list[0] /* address, for backward compat */
};
h_name涓轟富鏈哄悕瀛椼?br>h_aliases涓轟富鏈哄埆鍚嶅垪琛ㄣ?br>h_addrtype涓哄湴鍧綾誨瀷銆?br>h_length涓哄湴鍧綾誨瀷銆?br>h_addr_list涓篒P鍦板潃錛屽鏋滆涓繪満鏈夊涓綉鍗★紝灝卞寘鎷湴鍧鐨勫垪琛ㄣ傚彟澶栬繕鏈夊嚑涓被浼肩殑緇撴瀯錛岃繖閲屽氨涓嶄竴涓浠嬬粛浜?jiǎn)銆?/p>
#define IPPROTO_ICMP 1
#define IPPROTO_IGMP 2
#define IPPROTO_TCP 6
#define IPPROTO_UDP 17
#define IPPROTO_RAW 255 鍏蜂綋鏄粈涔堝崗璁紝澶у涓鐪嬪氨鐭ラ亾浜?jiǎn)銆?/p>
#define SO_DEBUG 0x0001 /* turn on debugging info recording */
//鏄惁鐩戝惉妯″紡
#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */
//濂楁帴瀛椾笌鍏朵粬濂楁帴瀛楃殑鍦板潃緇戝畾
#define SO_REUSEADDR 0x0004 /* allow local address reuse */
//淇濇寔榪炴帴
#define SO_KEEPALIVE 0x0008 /* keep connections alive */
//涓嶈璺敱鍑哄幓
#define SO_DONTROUTE 0x0010 /* just use interface addresses */
//璁劇疆涓哄箍鎾?br>#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */
//浣跨敤鐜洖涓嶉氳繃紜歡
#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */
//褰撳墠鎷栧歡鍊?br>#define SO_LINGER 0x0080 /* linger on close if data present */
//鏄惁鍔犲叆甯﹀鏁版嵁
#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */
//紱佺敤LINGER閫夐」
#define SO_DONTLINGER (int)(~SO_LINGER)
//鍙戦佺紦鍐插尯闀垮害
#define SO_SNDBUF 0x1001 /* send buffer size */
//鎺ユ敹緙撳啿鍖洪暱搴?br>#define SO_RCVBUF 0x1002 /* receive buffer size */
//鍙戦佽秴鏃舵椂闂?br>#define SO_SNDTIMEO 0x1005 /* send timeout */
//鎺ユ敹瓚呮椂鏃墮棿
#define SO_RCVTIMEO 0x1006 /* receive timeout */
//閿欒鐘舵?br>#define SO_ERROR 0x1007 /* get error status and clear */
//濂楁帴瀛楃被鍨?br>#define SO_TYPE 0x1008 /* get socket type */2銆?璇誨彇socket灞炴э細(xì)
//鏉ヨ嚜MS platform SDK 20033銆?璁劇疆socket灞炴э細(xì)
wVersionRequested=MAKEWORD(2,0)
鎴栬呯洿鎺ヨ祴鍊鹼細(xì)wVersionRequested=2
WORD wVersion;
WORD wHighVersion;
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
} WSADATA, FAR * LPWSADATA;濡傛灉鍔犺澆鎴愬姛鍚庢暟鎹負(fù)錛?/p>
szSystemStatus="Running"琛ㄧず姝e湪榪愯銆?br>iMaxSockets錛?琛ㄧず鍚屾椂鎵撳紑鐨剆ocket鏈澶ф暟錛屼負(fù)0琛ㄧず娌℃湁闄愬埗銆?br>iMaxUdpDg錛?琛ㄧず鍚屾椂鎵撳紑鐨勬暟鎹姤鏈澶ф暟錛屼負(fù)0琛ㄧず娌℃湁闄愬埗銆?br>lpVendorInfo娌℃湁浣跨敤錛屼負(fù)鍘傚晢鎸囧畾淇℃伅棰勭暀銆傝鍑芥暟浣跨敤鏂規(guī)硶錛?/p>
WSADATA wsData;
int nResult= WSAStartup(wVersion,&wsData);
if(nResult !=0)
{
//閿欒澶勭悊
}2銆佸垱寤哄鎺ュ瓧錛氾紙鏈嶅姟鍣ㄧ鍜屽鎴風(fēng)錛?/p>
af涓虹綉緇滃湴鍧綾誨瀷錛屼竴鑸負(fù)AF_INET錛岃〃紺哄湪Internet鍩熶腑浣跨敤銆?br>type涓哄鎺ュ瓧綾誨瀷錛屽墠闈㈠凡緇忎粙緇嶄簡(jiǎn)銆?br>protocol涓烘寚瀹氱綉緇滃崗璁紝涓鑸負(fù)IPPROTO_IP銆傜敤娉曪細(xì)
if(sock==INVALID_SOCKET)
{
//閿欒澶勭悊
}3銆佸鎺ュ瓧鐨勭粦瀹氾細(xì)灝嗘湰鍦板湴鍧緇戝畾鍒版墍鍒涘緩鐨勫鎺ュ瓧涓娿傦紙鏈嶅姟鍣ㄧ鍜屽鎴風(fēng)錛?/p>
s涓哄凡緇忓垱寤虹殑濂楁帴瀛椼?br>name涓簊ocket鍦板潃緇撴瀯錛屼負(fù)sockaddr緇撴瀯錛屽鍓嶉潰璁ㄨ鐨勶紝鎴戜滑涓鑸嬌鐢╯ockaddr_in
緇撴瀯錛屽湪浣跨敤鍐嶅己鍒惰漿鎹負(fù)sockaddr緇撴瀯銆?br>namelen涓哄湴鍧緇撴瀯鐨勯暱搴︺?br>鐢ㄦ硶錛?/p>
addr. sin_family=AF_INET;
addr. sin_port= htons(0); //淇濊瘉瀛楄妭欏哄簭
addr. sin_addr.s_addr= inet_addr("192.1.8.84")
int nResult=bind(s,(sockaddr*)&addr,sizeof(sockaddr));
if(nResult==SOCKET_ERROR)
{
//閿欒澶勭悊
}4銆?濂楁帴瀛楃殑鐩戝惉錛氾紙鏈嶅姟鍣ㄧ錛?/p>
浠ユ彁渚涘涓繛鎺ャ?br>鐢ㄦ硶錛?/p>
{
//閿欒澶勭悊
}5銆佸鎺ュ瓧絳夊緟榪炴帴:錛氾紙鏈嶅姟鍣ㄧ錛?/p>
SOCKET s_d=accept(s,(sockaddr*)&addr,sizeof(sockaddr));
if(s==INVALID_SOCKET)
{
//閿欒澶勭悊
}6銆佸鎺ュ瓧鐨勮繛緇擄細(xì)灝嗕袱涓鎺ュ瓧榪炵粨璧鋒潵鍑嗗閫氫俊銆傦紙瀹㈡埛绔級(jí)
addr. sin_family=AF_INET;
addr. sin_port=htons(0); //淇濊瘉瀛楄妭欏哄簭
addr. sin_addr.s_addr= htonl(INADDR_ANY) //淇濊瘉瀛楄妭欏哄簭
int nResult=connect(s,(sockaddr*)&addr,sizeof(sockaddr));
if(nResult==SOCKET_ERROR)
{
//閿欒澶勭悊
}7銆佸鎺ュ瓧鍙戦佹暟鎹細(xì)錛堟湇鍔″櫒绔拰瀹㈡埛绔級(jí)
#define MSG_PEEK 0x2 /* peek at incoming message */
#define MSG_DONTROUTE 0x4 /* send without using routing tables */
MSG_OOB琛ㄧず鏁版嵁搴旇甯﹀鍙戦侊紝鎵璋撳甫澶栨暟鎹氨鏄疶CP绱фユ暟鎹?br>MSG_PEEK琛ㄧず浣挎湁鐢ㄧ殑鏁版嵁澶嶅埗鍒扮紦鍐插尯鍐咃紝浣嗗茍涓嶄粠緋葷粺緙撳啿鍖哄唴鍒犻櫎銆?br>MSG_DONTROUTE琛ㄧず涓嶈灝嗗寘璺敱鍑哄幓銆?/p>
int nResult=send(s,buf,strlen(buf));
if(nResult==SOCKET_ERROR)
{
//閿欒澶勭悊
}8銆?濂楁帴瀛楃殑鏁版嵁鎺ユ敹錛氾紙瀹㈡埛绔級(jí)
int nResult =recv(s,mess,1000,0);
if(nResult==SOCKET_ERROR)
{
//閿欒澶勭悊
}9銆佷腑鏂鎺ュ瓧榪炴帴錛氶氱煡鏈嶅姟鍣ㄧ鎴栧鎴風(fēng)鍋滄鎺ユ敹鍜屽彂閫佹暟鎹傦紙鏈嶅姟鍣ㄧ鍜屽鎴風(fēng)錛?/p>
#define SD_SEND 0x01
#define SD_BOTH 0x02鐢ㄦ硶錛?/p>
if(nResult==SOCKET_ERROR)
{
//閿欒澶勭悊
}10銆?鍏抽棴濂楁帴瀛楋細(xì)閲婃斁鎵鍗犳湁鐨勮祫婧愩傦紙鏈嶅姟鍣ㄧ鍜屽鎴風(fēng)錛?/p>
if(nResult==SOCKET_ERROR)
{
//閿欒澶勭悊
}
]]>
涓錛歴elect妯″瀷
浜岋細(xì)WSAAsyncSelect妯″瀷
涓夛細(xì)WSAEventSelect妯″瀷
鍥涳細(xì)Overlapped I/O 浜嬩歡閫氱煡妯″瀷
浜旓細(xì)Overlapped I/O 瀹屾垚渚嬬▼妯″瀷
鍏細(xì)IOCP妯″瀷
鍘熸枃鍚嶏細(xì)銆婂熀浜嶥elphi鐨凷ocket I/O妯″瀷鍏ㄦ帴瑙?nbsp;銆?
鑰侀檲鏈変竴涓湪澶栧湴宸ヤ綔鐨勫コ鍎匡紝涓嶈兘緇忓父鍥炴潵錛岃侀檲鍜屽ス閫氳繃淇′歡鑱旂郴銆備粬浠殑淇′細(xì)琚偖閫掑憳鎶曢掑埌浠栦滑鐨勪俊綆遍噷銆?nbsp;
榪欏拰Socket妯″瀷闈炲父綾諱技銆備笅闈㈡垜灝變互鑰侀檲鎺ユ敹淇′歡涓轟緥璁茶ВSocket I/O妯″瀷銆?nbsp;
涓錛歴elect妯″瀷
鑰侀檲闈炲父鎯崇湅鍒板コ鍎跨殑淇°備互鑷充簬浠栨瘡闅?0鍒嗛挓灝變笅妤兼鏌ヤ俊綆憋紝鐪嬫槸鍚︽湁濂沖効鐨勪俊錛屽湪榪欑鎯呭喌涓嬶紝“涓嬫ゼ媯(gè)鏌ヤ俊綆?#8221;鐒跺悗鍥炲埌妤間笂鑰借浜?jiǎn)鑰侀檲澶鐨勬椂闂達(dá)紝浠ヨ嚦浜庤侀檲鏃犳硶鍋氬叾浠栧伐浣溿?nbsp;
select妯″瀷鍜岃侀檲鐨勮繖縐嶆儏鍐甸潪甯哥浉浼鹼細(xì)鍛ㄨ屽濮嬪湴鍘繪鏌?.....濡傛灉鏈夋暟鎹?.....鎺ユ敹/鍙戦?......
浣跨敤綰跨▼鏉elect搴旇鏄氱敤鐨勫仛娉曪細(xì)
procedure TListenThread.Execute;
var
銆 addr : TSockAddrIn;
銆 fd_read : TFDSet;
銆 timeout : TTimeVal;
銆 ASock,
銆 MainSock : TSocket;
銆 len, i : Integer;
begin
銆 MainSock := socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
銆 addr.sin_family := AF_INET;
銆 addr.sin_port := htons(5678);
銆 addr.sin_addr.S_addr := htonl(INADDR_ANY);
銆 bind( MainSock, @addr, sizeof(addr) );
銆 listen( MainSock, 5 );
銆 while (not Terminated) do
銆 begin
銆銆 FD_ZERO( fd_read );
銆銆 FD_SET( MainSock, fd_read );
銆銆 timeout.tv_sec := 0;
銆銆 timeout.tv_usec := 500;
銆銆 if select( 0, @fd_read, nil, nil, @timeout ) > 0 then //鑷沖皯鏈?涓瓑寰匒ccept鐨刢onnection
銆銆 begin
銆銆銆 if FD_ISSET( MainSock, fd_read ) then
銆銆銆 begin
銆銆銆 for i:=0 to fd_read.fd_count-1 do //娉ㄦ剰錛宖d_count <= 64錛?
涔熷氨鏄select鍙兘鍚屾椂綆$悊鏈澶?4涓繛鎺?nbsp;
銆銆銆 begin
銆銆銆銆 len := sizeof(addr);
銆銆銆銆 ASock := accept( MainSock, addr, len );
銆銆銆銆 if ASock <> INVALID_SOCKET then
銆銆銆銆銆 ....//涓篈Sock鍒涘緩涓涓柊鐨勭嚎紼嬶紝鍦ㄦ柊鐨勭嚎紼嬩腑鍐嶄笉鍋滃湴select
銆銆銆銆 end;
銆銆銆 end; 銆銆
銆銆 end;
銆 end; //while (not self.Terminated)
銆 shutdown( MainSock, SD_BOTH );
銆 closesocket( MainSock );
end;
浜岋細(xì)WSAAsyncSelect妯″瀷
鍚庢潵錛岃侀檲浣跨敤浜?jiǎn)寰蒋鍏徃鐨勬柊寮忎俊绠便傝繖縐嶄俊綆遍潪甯稿厛榪涳紝涓鏃︿俊綆遍噷鏈夋柊鐨勪俊浠訛紝鐩栬尐灝變細(xì)緇欒侀檲鎵撶數(shù)璇濓細(xì)鍠傦紝澶х埛錛屼綘鏈夋柊鐨勪俊浠朵簡(jiǎn)錛佷粠姝わ紝鑰侀檲鍐嶄篃涓嶅繀棰戠箒涓婁笅妤兼鏌ヤ俊綆變簡(jiǎn)錛岀墮涔熶笉鐤間簡(jiǎn)錛屼綘鐬呭噯浜?jiǎn)锛岃摑澶?.....涓嶆槸錛屽井杞?.....
寰蔣鎻愪緵鐨刉SAAsyncSelect妯″瀷灝辨槸榪欎釜鎰忔濄?nbsp;
WSAAsyncSelect妯″瀷鏄疻indows涓嬫渶綆鍗曟槗鐢ㄧ殑涓縐峉ocket I/O妯″瀷銆備嬌鐢ㄨ繖縐嶆ā鍨嬫椂錛學(xué)indows浼?xì)鎶娋|戠粶浜嬩歡浠ユ秷鎭殑褰㈠娍閫氱煡搴旂敤紼嬪簭銆?nbsp;
棣栧厛瀹氫箟涓涓秷鎭爣紺哄父閲忥細(xì)
const WM_SOCKET = WM_USER + 55;
鍐嶅湪涓籉orm鐨刾rivate鍩熸坊鍔犱竴涓鐞嗘娑堟伅鐨勫嚱鏁板0鏄庯細(xì)
private
procedure WMSocket(var Msg: TMessage); message WM_SOCKET;
銆
鐒跺悗灝卞彲浠ヤ嬌鐢╓SAAsyncSelect浜?jiǎn)锛?xì)
var
銆 addr : TSockAddr;
銆 sock : TSocket;
銆 sock := socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
銆 addr.sin_family := AF_INET;
銆 addr.sin_port := htons(5678);
銆 addr.sin_addr.S_addr := htonl(INADDR_ANY);
銆 bind( m_sock, @addr, sizeof(SOCKADDR) );
銆 WSAAsyncSelect( m_sock, Handle, WM_SOCKET, FD_ACCEPT or FD_CLOSE );
銆 listen( m_sock, 5 );
銆 ....
搴旂敤紼嬪簭鍙互瀵規(guī)敹鍒癢M_SOCKET娑堟伅榪涜鍒嗘瀽錛屽垽鏂槸鍝竴涓猻ocket浜х敓浜?jiǎn)缃懢l滀簨浠朵互鍙?qiáng)浜嬩欢绫诲瀷锛?xì)
procedure TfmMain.WMSocket(var Msg: TMessage);
var
銆 sock : TSocket;
銆 addr : TSockAddrIn;
銆 addrlen : Integer;
銆 buf : Array [0..4095] of Char;
begin
銆 //Msg鐨刉Param鏄駭鐢熶簡(jiǎn)緗戠粶浜嬩歡鐨剆ocket鍙ユ焺錛孡Param鍒欏寘鍚簡(jiǎn)浜嬩歡綾誨瀷
銆 case WSAGetSelectEvent( Msg.LParam ) of
銆 FD_ACCEPT :
銆銆 begin
銆銆銆 addrlen := sizeof(addr);
銆銆銆 sock := accept( Msg.WParam, addr, addrlen );
銆銆銆 if sock <> INVALID_SOCKET then
銆銆銆銆 WSAAsyncSelect( sock, Handle, WM_SOCKET, FD_READ or FD_WRITE or FD_CLOSE );
銆銆 end;
銆銆 FD_CLOSE : closesocket( Msg.WParam );
銆銆 FD_READ : recv( Msg.WParam, buf[0], 4096, 0 );
銆銆 FD_WRITE : ;
銆 end;
end;
涓夛細(xì)WSAEventSelect妯″瀷
鍚庢潵錛屽井杞殑淇$闈炲父鐣呴攢錛岃喘涔板井杞俊綆辯殑浜轟互鐧句竾璁℃暟......浠ヨ嚦浜庣洊鑼ㄦ瘡澶?4灝忔椂緇欏鎴鋒墦鐢?shù)璇濆Q岀瘡寰楄叞閰歌儗鐥涳紝鍠濊殎鍔涚閮戒笉濂戒嬌銆傚井杞敼榪涗簡(jiǎn)浠栦滑鐨勪俊綆憋細(xì)鍦ㄥ鎴風(fēng)殑瀹朵腑娣誨姞涓涓檮鍔犺緗紝榪欎釜瑁呯疆浼?xì)鐩戣瀹㈡堬L(fēng)殑淇$錛屾瘡褰撴柊鐨勪俊浠舵潵涓達(dá)紝姝よ緗細(xì)鍙戝嚭“鏂頒俊浠跺埌杈?#8221;澹幫紝鎻愰啋鑰侀檲鍘繪敹淇°傜洊鑼ㄧ粓浜庡彲浠ョ潯瑙変簡(jiǎn)銆?nbsp;
鍚屾牱瑕佷嬌鐢ㄧ嚎紼嬶細(xì)
procedure TListenThread.Execute;
var
銆 hEvent : WSAEvent;
銆 ret : Integer;
銆 ne : TWSANetworkEvents;
銆 sock : TSocket;
銆 adr : TSockAddrIn;
銆 sMsg : String;
銆 Index,
銆 EventTotal : DWORD;
銆 EventArray : Array [0..WSA_MAXIMUM_WAIT_EVENTS-1] of WSAEVENT;
begin
銆 ...socket...bind...
銆 hEvent := WSACreateEvent();
銆 WSAEventSelect( ListenSock, hEvent, FD_ACCEPT or FD_CLOSE );
銆 ...listen...
銆 while ( not Terminated ) do
銆 begin
銆銆 Index := WSAWaitForMultipleEvents( EventTotal, @EventArray[0], FALSE,
WSA_INFINITE, FALSE );
銆銆 FillChar( ne, sizeof(ne), 0 );
銆銆 WSAEnumNetworkEvents( SockArray[Index-WSA_WAIT_EVENT_0],
EventArray
[Index-WSA_WAIT_EVENT_0], @ne );
銆銆 if ( ne.lNetworkEvents and FD_ACCEPT ) > 0 then
銆銆 begin
銆銆銆 if ne.iErrorCode[FD_ACCEPT_BIT] <> 0 then
銆銆銆銆 continue;
銆銆銆 ret := sizeof(adr);
銆銆銆 sock := accept( SockArray[Index-WSA_WAIT_EVENT_0], adr, ret );
銆銆銆 if EventTotal > WSA_MAXIMUM_WAIT_EVENTS-1 then
//榪欓噷W(xué)SA_MAXIMUM_WAIT_EVENTS鍚屾牱鏄?4
銆銆銆 begin
銆銆銆銆 closesocket( sock );
銆銆銆銆 continue;
銆銆銆 end;
銆銆銆 hEvent := WSACreateEvent();
銆銆銆 WSAEventSelect( sock, hEvent, FD_READ or FD_WRITE or FD_CLOSE );
銆銆銆 SockArray[EventTotal] := sock;
銆銆銆 EventArray[EventTotal] := hEvent;
銆銆銆 Inc( EventTotal );
銆銆 end;
銆銆 if ( ne.lNetworkEvents and FD_READ ) > 0 then
銆銆 begin
銆銆銆 if ne.iErrorCode[FD_READ_BIT] <> 0 then
銆銆銆銆 continue;
銆銆銆銆 FillChar( RecvBuf[0], PACK_SIZE_RECEIVE, 0 );
銆銆銆銆 ret := recv( SockArray[Index-WSA_WAIT_EVENT_0], RecvBuf[0],
PACK_SIZE_RECEIVE, 0 );
銆銆銆銆 ......
銆銆銆 end;
銆銆 end;
end;
鍥涳細(xì)Overlapped I/O 浜嬩歡閫氱煡妯″瀷
鍚庢潵錛屽井杞氳繃璋冩煡鍙戠幇錛岃侀檲涓嶅枩嬈笂涓嬫ゼ鏀跺彂淇′歡錛屽洜涓轟笂涓嬫ゼ鍏跺疄寰堟氮璐規(guī)椂闂淬備簬鏄井杞啀嬈℃敼榪涗粬浠殑淇$銆傛柊寮忕殑淇$閲囩敤浜?jiǎn)鏇翠负鍏垬q涚殑鎶鏈紝鍙鐢ㄦ埛鍛婅瘔寰蔣鑷繁鐨勫鍦ㄥ嚑妤煎嚑鍙鳳紝鏂板紡淇$浼?xì)鎶婁俊錃g鐩存帴浼犻佸埌鐢ㄦ埛鐨勫涓紝鐒跺悗鍛婅瘔鐢ㄦ埛錛屼綘鐨勪俊浠跺凡緇忔斁鍒頒綘鐨勫涓簡(jiǎn)錛佽侀檲寰堥珮鍏達(dá)紝鍥犱負(fù)浠栦笉蹇呭啀浜茶嚜鏀跺彂淇′歡浜?jiǎn)锛?nbsp;
Overlapped I/O 浜嬩歡閫氱煡妯″瀷鍜學(xué)SAEventSelect妯″瀷鍦ㄥ疄鐜頒笂闈炲父鐩鎬技錛屼富瑕佸尯鍒湪"Overlapped”錛孫verlapped妯″瀷鏄搴旂敤紼嬪簭浣跨敤閲嶅彔鏁版嵁緇撴瀯(WSAOVERLAPPED)錛屼竴嬈℃姇閫掍竴涓垨澶氫釜Winsock I/O璇鋒眰銆傝繖浜涙彁浜ょ殑璇鋒眰瀹屾垚鍚庯紝搴旂敤紼嬪簭浼?xì)鏀跺埌閫氱煡銆備粈涔堟剰鎬濆憿錛熷氨鏄錛屽鏋滀綘鎯充粠socket涓婃帴鏀舵暟鎹紝鍙渶瑕佸憡璇夌郴緇燂紝鐢辯郴緇熶負(fù)浣犳帴鏀舵暟鎹紝鑰屼綘闇瑕佸仛鐨勫彧鏄負(fù)緋葷粺鎻愪緵涓涓紦鍐插尯~~~~~
Listen綰跨▼鍜學(xué)SAEventSelect妯″瀷涓妯′竴鏍鳳紝Recv/Send綰跨▼鍒欏畬鍏ㄤ笉鍚岋細(xì)
procedure TOverlapThread.Execute;
var
銆 dwTemp : DWORD;
銆 ret : Integer;
銆 Index : DWORD;
begin
銆 ......
銆 while ( not Terminated ) do
銆 begin
銆銆 Index := WSAWaitForMultipleEvents
( FLinks.Count, @FLinks.Events[0], FALSE,
RECV_TIME_OUT, FALSE );
銆銆 Dec( Index, WSA_WAIT_EVENT_0 );
銆銆 if Index > WSA_MAXIMUM_WAIT_EVENTS-1 then
//瓚呮椂鎴栬呭叾浠栭敊璇?nbsp;
銆銆銆 continue;
銆銆 WSAResetEvent
( FLinks.Events[Index] );
銆銆 WSAGetOverlappedResult( FLinks.Sockets[Index],
FLinks.pOverlaps[Index], @dwTemp, FALSE,FLinks.
pdwFlags[Index]^ );
銆銆 if dwTemp = 0 then //榪炴帴宸茬粡鍏抽棴
銆銆 begin
銆銆銆 ......
銆銆銆 continue;
銆銆 end else
銆 begin
銆銆 fmMain.ListBox1.Items.Add( FLinks.pBufs[Index]^.buf );
銆 end;
銆 //鍒濆鍖栫紦鍐插尯
銆 FLinks.pdwFlags[Index]^ := 0;
銆 FillChar( FLinks.pOverlaps[Index]^,
sizeof(WSAOVERLAPPED), 0 );
銆 FLinks.pOverlaps[Index]^.
hEvent := FLinks.Events[Index];
銆 FillChar( FLinks.pBufs[Index]^.buf^,
BUFFER_SIZE, 0 );
銆 //閫掍竴涓帴鏀舵暟鎹姹?nbsp;
銆 WSARecv( FLinks.Sockets[Index], FLinks.pBufs[Index], 1,
FLinks.pdwRecvd[Index]^, FLinks.pdwFlags[Index]^,
FLinks.pOverlaps[Index], nil );
end;
end;
浜旓細(xì)Overlapped I/O 瀹屾垚渚嬬▼妯″瀷
鑰侀檲鎺ユ敹鍒版柊鐨勪俊浠跺悗錛屼竴鑸殑紼嬪簭鏄細(xì)鎵撳紑淇″皝----鎺忓嚭淇$焊----闃呰淇′歡----鍥炲淇′歡......涓轟簡(jiǎn)榪涗竴姝ュ噺杞葷敤鎴瘋礋鎷咃紝寰蔣鍙堝紑鍙戜簡(jiǎn)涓縐嶆柊鐨勬妧鏈細(xì)鐢ㄦ埛鍙鍛婅瘔寰蔣瀵逛俊浠剁殑鎿嶄綔姝ラ錛屽井杞俊綆卞皢鎸夌収榪欎簺姝ラ鍘誨鐞嗕俊浠訛紝涓嶅啀闇瑕佺敤鎴蜂翰鑷媶淇?闃呰/鍥炲浜?jiǎn)锛佽侀檲緇堜簬榪囦笂浜?jiǎn)灏忚祫鐢煁z伙紒
Overlapped I/O 瀹屾垚渚嬬▼瑕佹眰鐢ㄦ埛鎻愪緵涓涓洖璋冨嚱鏁幫紝鍙戠敓鏂扮殑緗戠粶浜嬩歡鐨勬椂鍊欑郴緇熷皢鎵ц榪欎釜鍑芥暟錛?nbsp;
procedure WorkerRoutine( const dwError, cbTransferred : DWORD;
const
lpOverlapped : LPWSAOVERLAPPED; const dwFlags : DWORD ); stdcall;
鐒跺悗鍛婅瘔緋葷粺鐢╓orkerRoutine鍑芥暟澶勭悊鎺ユ敹鍒扮殑鏁版嵁錛?nbsp;
WSARecv( m_socket, @FBuf, 1, dwTemp, dwFlag, @m_overlap, WorkerRoutine );
銆銆 鐒跺悗......娌℃湁浠涔堢劧鍚庝簡(jiǎn)錛岀郴緇熶粈涔堥兘緇欎綘鍋氫簡(jiǎn)錛佸井杞湡瀹炰綋璐達(dá)紒
while ( not Terminated ) do//榪欏氨鏄竴涓猂ecv/Send綰跨▼瑕佸仛鐨勪簨鎯?.....浠涔堥兘涓嶇敤鍋氬晩錛侊紒錛?nbsp;
begin
銆 if SleepEx( RECV_TIME_OUT, True ) = WAIT_IO_COMPLETION then //
銆 begin
銆銆 ;
銆 end else
銆 begin
銆銆 continue;
銆 end;
end;
鍏細(xì)IOCP妯″瀷
寰蔣淇$浼間箮寰堝畬緹庯紝鑰侀檲涔熷緢婊℃剰銆備絾鏄湪涓浜涘ぇ鍏徃鎯呭喌鍗村畬鍏ㄤ笉鍚岋紒榪欎簺澶у叕鍙告湁鏁頒互涓囪鐨勪俊綆憋紝姣忕閽熼兘鏈夋暟浠ョ櫨璁$殑淇′歡闇瑕佸鐞嗭紝浠ヨ嚦浜庡井杞俊綆辯粡甯稿洜瓚呰礋鑽瘋繍杞屽穿婧冿紒闇瑕侀噸鏂板惎鍔紒寰蔣涓嶅緱涓嶄嬌鍑烘潃鎵嬮攺......
寰蔣緇欐瘡涓ぇ鍏徃媧句簡(jiǎn)涓鍚嶅悕鍙?#8220;Completion Port”鐨勮秴綰ф満鍣ㄤ漢錛岃榪欎釜鏈哄櫒浜哄幓澶勭悊閭d簺淇′歡錛?nbsp;
“Windows NT灝忕粍娉ㄦ剰鍒拌繖浜涘簲鐢ㄧ▼搴忕殑鎬ц兘娌℃湁棰勬枡鐨勯偅涔堥珮銆傜壒鍒殑錛屽鐞嗗緢澶氬悓鏃剁殑瀹㈡埛璇鋒眰鎰忓懗鐫寰堝綰跨▼騫跺彂鍦拌繍琛屽湪緋葷粺涓傚洜涓烘墍鏈夎繖浜涚嚎紼嬮兘鏄彲榪愯鐨刐娌℃湁琚寕璧峰拰絳夊緟鍙戠敓浠涔堜簨]錛孧icrosoft鎰忚瘑鍒癗T鍐呮牳鑺辮垂浜?jiǎn)澶鐨勬棄櫁存潵铦{鎹㈣繍琛岀嚎紼嬬殑涓婁笅鏂嘯Context]錛岀嚎紼嬪氨娌℃湁寰楀埌寰堝CPU鏃墮棿鏉ュ仛瀹冧滑鐨勫伐浣溿傚ぇ瀹跺彲鑳戒篃閮芥劅瑙夊埌騫惰妯″瀷鐨勭摱棰堝湪浜庡畠涓烘瘡涓涓鎴瘋姹傞兘鍒涘緩浜?jiǎn)涓涓柊綰跨▼銆傚垱寤虹嚎紼嬫瘮璧峰垱寤鴻繘紼嬪紑閿瑕佸皬錛屼絾涔熻繙涓嶆槸娌℃湁寮閿鐨勩傛垜浠笉濡ㄨ鎯充竴涓嬶細(xì)濡傛灉浜嬪厛寮濂絅涓嚎紼嬶紝璁╁畠浠湪閭old[鍫靛]錛岀劧鍚庡彲浠ュ皢鎵鏈夌敤鎴風(fēng)殑璇鋒眰閮芥姇閫掑埌涓涓秷鎭槦鍒椾腑鍘匯傜劧鍚庨偅N涓嚎紼嬮愪竴浠庢秷鎭槦鍒椾腑鍘誨彇鍑烘秷鎭茍鍔犱互澶勭悊銆傚氨鍙互閬垮厤閽堝姣忎竴涓敤鎴瘋姹傞兘寮綰跨▼銆備笉浠呭噺灝戜簡(jiǎn)綰跨▼鐨勮祫婧愶紝涔熸彁楂樹(shù)簡(jiǎn)綰跨▼鐨勫埄鐢ㄧ巼銆傜悊璁轟笂寰堜笉閿欙紝浣犳兂鎴戠瓑娉涙硾涔嬭緢閮借兘鎯沖嚭鏉ョ殑闂錛孧icrosoft鍙堟庝細(xì)娌℃湁鑰冭檻鍒板憿?”-----鎽樿嚜nonocast鐨勩婄悊瑙/O Completion Port銆?nbsp;
鍏堢湅涓涓婭OCP妯″瀷鐨勫疄鐜幫細(xì)
//鍒涘緩涓涓畬鎴愮鍙?nbsp;
FCompletPort := CreateIoCompletionPort( INVALID_HANDLE_VALUE, 0,0,0 );
//鎺ュ彈榪滅▼榪炴帴錛屽茍鎶婅繖涓繛鎺ョ殑socket鍙ユ焺緇戝畾鍒板垰鎵嶅垱寤虹殑IOCP涓?nbsp;
AConnect := accept( FListenSock, addr, len);
CreateIoCompletionPort( AConnect, FCompletPort, nil, 0 );
//鍒涘緩CPU鏁?2 + 2涓嚎紼?nbsp;
for i:=1 to si.dwNumberOfProcessors*2+2 do
begin
銆 AThread := TRecvSendThread.Create( false );
銆 AThread.CompletPort := FCompletPort;//鍛婅瘔榪欎釜綰跨▼錛屼綘瑕佸幓榪欎釜IOCP鍘昏闂暟鎹?nbsp;
end;
灝辮繖涔堢畝鍗曪紝鎴戜滑瑕佸仛鐨勫氨鏄緩绔嬩竴涓狪OCP錛屾妸榪滅▼榪炴帴鐨剆ocket鍙ユ焺緇戝畾鍒板垰鎵嶅垱寤虹殑IOCP涓婏紝鏈鍚庡垱寤簄涓嚎紼嬶紝騫跺憡璇夎繖n涓嚎紼嬪埌榪欎釜IOCP涓婂幓璁塊棶鏁版嵁灝卞彲浠ヤ簡(jiǎn)銆?nbsp;
鍐嶇湅涓涓婽RecvSendThread綰跨▼閮藉共浜涗粈涔堬細(xì)
procedure TRecvSendThread.Execute;
var
銆 ......
begin
銆 while (not self.Terminated) do
銆 begin
銆銆 //鏌ヨIOCP鐘舵侊紙鏁版嵁璇誨啓鎿嶄綔鏄惁瀹屾垚錛?nbsp;
銆銆 GetQueuedCompletionStatus( CompletPort, BytesTransd,
CompletKey, POVERLAPPED(pPerIoDat), TIME_OUT );
銆銆 if BytesTransd <> 0 then
銆銆銆 ....;//鏁版嵁璇誨啓鎿嶄綔瀹屾垚
銆銆
銆銆銆 //鍐嶆姇閫掍竴涓鏁版嵁璇鋒眰
銆銆銆 WSARecv( CompletKey, @(pPerIoDat^.BufData), 1,
BytesRecv, Flags, @(pPerIoDat^.Overlap), nil );
銆銆 end;
end;
璇誨啓綰跨▼鍙槸綆鍗曞湴媯(gè)鏌OCP鏄惁瀹屾垚浜?jiǎn)鎴戜滑鎶曢掔殑璇誨啓鎿嶄綔錛屽鏋滃畬鎴愪簡(jiǎn)鍒欏啀鎶曢掍竴涓柊鐨勮鍐欒姹傘?nbsp;
搴旇娉ㄦ剰鍒幫紝鎴戜滑鍒涘緩鐨勬墍鏈塗RecvSendThread閮藉湪璁塊棶鍚屼竴涓狪OCP錛堝洜涓烘垜浠彧鍒涘緩浜?jiǎn)涓涓狪OCP錛夛紝騫朵笖鎴戜滑娌℃湁浣跨敤涓寸晫鍖猴紒闅鵑亾涓嶄細(xì)浜х敓鍐茬獊鍚楋紵涓嶇敤鑰冭檻鍚屾闂鍚楋紵
榪欐鏄疘OCP鐨勫ゥ濡欐墍鍦ㄣ侷OCP涓嶆槸涓涓櫘閫氱殑瀵硅薄錛屼笉闇瑕佽冭檻綰跨▼瀹夊叏闂銆傚畠浼?xì)鑷姩璋冮厤璁块棶瀹冪殑绾拷E嬶細(xì)濡傛灉鏌愪釜socket涓婃湁涓涓嚎紼婣姝e湪璁塊棶錛岄偅涔堢嚎紼婤鐨勮闂姹備細(xì)琚垎閰嶅埌鍙﹀涓涓猻ocket銆傝繖涓鍒囬兘鏄敱緋葷粺鑷姩璋冮厤鐨勶紝鎴戜滑鏃犻渶榪囬棶銆?
]]>