锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
]]>
]]>
]]>
]]>
鎵浠ユ垜灝辨煡浜嗕竴涓婱SDN,鍙戠幇鏈塕outing and Remote Access Service涓綾葷殑API鍙互鐢ㄣ?br />浜庢槸紼嬪簭鐨勬祦紼嬪氨鏄繖鏍?br />1.璁劇疆涓存椂闃茬伀澧欙紝浠ラ樆鎸″彂鍒扮鍙?1113鐨刄DP鍖?br />2.鍚姩閲戝北璇嶉湼
3.鍒犻櫎璁劇疆
浠g爜錛?br />
#include聽<stdlib.h>
#include聽<Iphlpapi.h>
#include聽<Fltdefs.h>
#pragma聽comment(lib,聽"Iphlpapi.lib")
const聽int聽XDICT_PORT聽=聽11113;
unsigned聽long聽CharToIp(const聽char聽*sIp)
{
聽聽聽聽int聽octets[4];
聽聽聽聽int聽i;
聽聽聽聽const聽char聽*聽auxCad聽=聽sIp;
聽聽聽聽unsigned聽long聽lIp聽=聽0;
聽聽聽聽
聽聽聽聽//we聽extract聽each聽octet聽of聽the聽ip聽address
聽聽聽聽//atoi聽will聽get聽characters聽until聽it聽found聽a聽non聽numeric聽character(in聽our聽case聽'.')
聽聽聽聽for(i聽=聽0;聽i聽<聽4;聽i++)
聽聽聽聽{
聽聽聽聽聽聽聽聽octets[i]聽=聽atoi(auxCad);
聽聽聽聽聽聽聽聽if(octets[i]聽<聽0聽||聽octets[i]聽>聽255)
聽聽聽聽聽聽聽聽聽聽聽聽return聽0;
聽聽聽聽聽聽聽聽lIp聽|=聽(octets[i]聽<<聽(i*8));
聽聽聽聽聽聽聽聽//update聽auxCad聽to聽point聽to聽the聽next聽octet
聽聽聽聽聽聽聽聽auxCad聽=聽strchr(auxCad,聽'.');
聽聽聽聽聽聽聽聽if(auxCad聽==聽NULL聽&&聽i!=3)
聽聽聽聽聽聽聽聽聽聽聽聽return聽-1;
聽聽聽聽聽聽聽聽auxCad++;
聽聽聽聽}
聽聽聽聽return聽lIp;
}
int聽APIENTRY聽WinMain(HINSTANCE聽hInstance,
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽HINSTANCE聽hPrevInstance,
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽LPSTR聽聽聽聽聽lpCmdLine,
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽int聽聽聽聽聽聽聽nCmdShow)
{
聽聽聽聽//first聽get聽adapter聽info
聽聽聽聽PIP_ADAPTER_INFO聽pAdapterInfo聽=聽NULL,tmp;
聽聽聽聽unsigned聽long聽len聽=聽0;
聽聽聽聽聽GetAdaptersInfo(pAdapterInfo,&len);
聽聽聽聽pAdapterInfo聽=聽(PIP_ADAPTER_INFO)聽malloc聽(len);
聽聽聽聽DWORD聽result聽=聽GetAdaptersInfo(pAdapterInfo,聽&len);
聽聽聽聽if(result!=ERROR_SUCCESS)
聽聽聽聽{
聽聽聽聽聽聽聽聽MessageBox(NULL,"Fail聽to聽call聽GetAdaptersInfo","ERROR",MB_OK);
聽聽聽聽聽聽聽聽return聽-1;
聽聽聽聽}
聽聽聽聽//create聽filters聽interface
聽聽聽聽INTERFACE_HANDLE聽hInterface聽=聽NULL;
聽聽聽聽result聽=聽PfCreateInterface(0,PF_ACTION_FORWARD,PF_ACTION_FORWARD,FALSE,TRUE,&hInterface);
聽聽聽聽if(result!=NO_ERROR)
聽聽聽聽{
聽聽聽聽聽聽聽聽MessageBox(NULL,"Fail聽to聽call聽PfCreateInterface","ERROR",MB_OK);
聽聽聽聽聽聽聽聽return聽-1;
聽聽聽聽}
聽聽聽聽//add聽the聽filter聽to聽adapter
聽聽聽聽unsigned聽long聽dmp聽=聽0;
聽聽聽聽PF_FILTER_DESCRIPTOR聽ipFlt;
聽聽聽聽ipFlt.dwFilterFlags聽聽聽聽聽=聽0;
聽聽聽聽ipFlt.dwRule聽聽聽聽聽聽聽聽聽聽聽聽=聽0;
聽聽聽聽ipFlt.pfatType聽聽聽聽聽聽聽聽聽聽=聽PF_IPV4;
聽聽聽聽ipFlt.dwProtocol聽聽聽聽聽聽聽聽=聽FILTER_PROTO_UDP;
聽聽聽聽ipFlt.fLateBound聽聽聽聽聽聽聽聽=聽0;
聽聽聽聽ipFlt.wSrcPort聽聽聽聽聽聽聽聽聽聽=聽0;
聽聽聽聽ipFlt.wSrcPortHighRange聽=聽0;
聽聽聽聽ipFlt.wDstPort聽聽聽聽聽聽聽聽聽聽=聽XDICT_PORT;
聽聽聽聽ipFlt.wDstPortHighRange聽=聽XDICT_PORT;
聽聽聽聽ipFlt.SrcAddr聽=聽(PBYTE)&dmp聽;
聽聽聽聽ipFlt.SrcMask聽=聽(PBYTE)&dmp;
聽聽聽聽ipFlt.DstAddr聽=聽(PBYTE)&dmp;
聽聽聽聽ipFlt.DstMask聽=聽(PBYTE)&dmp;
聽聽聽聽//bind
聽聽聽聽IP_ADDR_STRING聽*localIp;
聽聽聽聽for(tmp=pAdapterInfo;tmp聽!=聽NULL;tmp=tmp->Next)
聽聽聽聽{
聽聽聽聽聽聽聽聽聽聽聽聽//聽each聽ip聽of聽a聽adapter
聽聽聽聽聽聽聽聽聽聽聽聽for(localIp=&tmp->IpAddressList;localIp!=NULL;localIp=localIp->Next)
聽聽聽聽聽聽聽聽聽聽聽聽{
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽unsigned聽long聽ul聽=聽CharToIp(localIp->IpAddress.String);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽PBYTE聽lIp聽=聽(PBYTE)&ul;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽PfBindInterfaceToIPAddress(hInterface,聽PF_IPV4,聽lIp);
聽聽聽聽聽聽聽聽聽聽聽聽}
聽聽聽聽}
聽聽聽聽result聽=聽PfAddFiltersToInterface(hInterface,1,&ipFlt,1,&ipFlt,NULL);
聽聽聽聽if(result!=NO_ERROR)
聽聽聽聽{
聽聽聽聽聽聽聽聽MessageBox(NULL,"Fail聽to聽call聽PfAddFiltersToInterface","ERROR",MB_OK);
聽聽聽聽聽聽聽聽return聽-1;
聽聽聽聽}
聽聽聽聽//start聽XDict
聽聽聽聽STARTUPINFO聽si;
聽聽聽聽PROCESS_INFORMATION聽pi;
聽聽聽聽ZeroMemory(聽&si,聽sizeof(si)聽);
聽聽聽聽si.cb聽=聽sizeof(si);
聽聽聽聽ZeroMemory(聽&pi,聽sizeof(pi)聽);
聽聽聽聽::CreateProcess(NULL,"XDICT.exe",
聽聽聽聽聽聽聽聽NULL,聽聽聽聽聽聽聽聽聽聽聽聽聽//聽Process聽handle聽not聽inheritable.聽
聽聽聽聽聽聽聽聽NULL,聽聽聽聽聽聽聽聽聽聽聽聽聽//聽Thread聽handle聽not聽inheritable.聽
聽聽聽聽聽聽聽聽FALSE,聽聽聽聽聽聽聽聽聽聽聽聽//聽Set聽handle聽inheritance聽to聽FALSE.聽
聽聽聽聽聽聽聽聽0,聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽//聽No聽creation聽flags.聽
聽聽聽聽聽聽聽聽NULL,聽聽聽聽聽聽聽聽聽聽聽聽聽//聽Use聽parent's聽environment聽block.聽
聽聽聽聽聽聽聽聽NULL,聽聽聽聽聽聽聽聽聽聽聽聽聽//聽Use聽parent's聽starting聽directory.聽
聽聽聽聽聽聽聽聽&si,聽聽聽聽聽聽聽聽聽聽聽聽聽聽//聽Pointer聽to聽STARTUPINFO聽structure.
聽聽聽聽聽聽聽聽&pi聽);聽聽聽聽聽聽聽聽聽聽聽聽//聽Pointer聽to聽PROCESS_INFORMATION聽structure.
聽聽聽聽//聽Wait聽until聽child聽process聽exits.
聽聽聽聽WaitForSingleObject(聽pi.hProcess,聽INFINITE聽);
聽聽聽聽//聽Close聽process聽and聽thread聽handles.聽
聽聽聽聽CloseHandle(聽pi.hProcess聽);
聽聽聽聽CloseHandle(聽pi.hThread聽);
聽聽聽聽//remove聽filter
聽聽聽聽for(tmp=pAdapterInfo;tmp聽!=聽NULL;tmp=tmp->Next)
聽聽聽聽{
聽聽聽聽聽聽聽聽result聽=聽PfRemoveFiltersFromInterface(hInterface,1,&ipFlt,1,&ipFlt);
聽聽聽聽聽聽聽聽if(result!=NO_ERROR)
聽聽聽聽聽聽聽聽{
聽聽聽聽聽聽聽聽聽聽聽聽MessageBox(NULL,"Fail聽to聽call聽PfRemoveFiltersFromInterface","ERROR",MB_OK);
聽聽聽聽聽聽聽聽聽聽聽聽return聽-1;
聽聽聽聽聽聽聽聽}
聽聽聽聽}
聽聽聽聽PfUnBindInterface(hInterface);聽
聽聽聽聽PfDeleteInterface(hInterface);
聽聽聽聽//free
聽聽聽聽free(pAdapterInfo);
聽聽聽聽return聽0;
}
浣跨敤鐨凙PI鏈?br />GetAdapaterInfo --- 鍙栧緱緗戝崱鐨勪俊鎭紝濡俰p
PfCreateInterface ----Create涓涓狥ilter Interface
PfBindInterfaceToIPAddress ----緇戝畾Filter Interface鍒癐P
PfAddFiltersToInterface ----澧炲姞Filter鍒癐nterface
PfRemoveFiltersFromInterface ---Remove Filter
PfUnBindInterface---鍙栨秷緇戝畾鍒癷p
PfDeleteInterface---鍒犻櫎Filter Interface
闄勪笂鍙墽琛屾枃浠? http://www.shnenglu.com/Files/sandy/XDictWrapper.zip
浣跨敤鐨勬椂鍊欒В鍘嬫斁鍦ㄩ噾灞辮瘝闇稿悓涓涓洰褰曞氨鍙互浜嗭紝鐒跺悗閫氳繃榪欎釜紼嬪簭鏉ュ惎鍔ㄩ噾灞辮瘝闇搞?img src ="http://www.shnenglu.com/sandy/aggbug/5891.html" width = "1" height = "1" />
]]>
浣犲彲浠ヨ嚜宸卞垱寤轟竴涓狝CE_Reactor
浣嗘槸澶у鏁版椂鍊欙紝鎴戜滑閮芥槸閫氳繃璋冪敤ACE_Reactor::instance()榪欎釜闈欐佹柟娉曟潵榪斿洖鍞竴鐨勫疄渚嬨?BR>
ACE_Reactor::instance (void)
{
ACE_TRACE ("ACE_Reactor::instance");
if (ACE_Reactor::reactor_ == 0) //1
{
// Perform Double-Checked Locking Optimization.
ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
*ACE_Static_Object_Lock::instance (), 0));
if (ACE_Reactor::reactor_ == 0) //2
{
ACE_NEW_RETURN (ACE_Reactor::reactor_,
ACE_Reactor,
0);
ACE_Reactor::delete_reactor_ = 1;
ACE_REGISTER_FRAMEWORK_COMPONENT(ACE_Reactor, ACE_Reactor::reactor_)
}
}
return ACE_Reactor::reactor_;
}
2. Impl鎵嬫硶鐨勮繍鐢?BR>ACE_Reactor鏈変釜鎴愬憳鍙橀噺 ACE_Reactor_Impl *implementation_;
榪欎釜implementation_鎵嶆槸鐪熸鍋氫簨鎯呯殑涓滆タ錛屽吀鍨嬬殑Impl鎵嬫硶銆?BR>涓轟粈涔堣澶氫竴涓繖涓棿闅斿眰鍛紝涓昏鏄負(fù)浜嗗疄鐜拌法騫沖彴銆?BR>鍥犱負(fù)涓嶅悓鐨勫鉤鍙扮殑Reactor宸紓寰堝ぇ銆?BR>鍦╓indows騫沖彴錛屽疄鐜拌繖涓槸ACE_WFMO_Reactor
3. Event_Handle鐨勭鐞?BR>ACE_WFMO_Reactor鎶婅綆$悊鐨凥andle閮芥斁鍦?ACE_WFMO_Reactor_Handler_Repository handler_rep_;
榪欓噷瑕佹敞鎰忕殑鏄痠o_handle鍜宔vent_handle鐨勫尯鍒?BR>io_handle鏄湡姝g殑handle錛屾瘮濡俿ocket_handle, thread_handle
鑰宔vent_handle鏄粦瀹氬湪io_handle涓婇潰鐨勪簨浠秇andle
鏈変唬鐮佷負(fù)璇?
2 ACE_WFMO_Reactor::register_handler_i (ACE_HANDLE event_handle,
3 ACE_HANDLE io_handle,
4 ACE_Event_Handler *event_handler,
5 ACE_Reactor_Mask new_masks)
6 {
7 // If this is a Winsock 1 system, the underlying event assignment will
8 // not work, so don't try. Winsock 1 must use ACE_Select_Reactor for
9 // reacting to socket activity.
10
11 // Make sure that the <handle> is valid
12 if (io_handle == ACE_INVALID_HANDLE)
13 io_handle = event_handler->get_handle ();
14
15 if (this->handler_rep_.invalid_handle (io_handle))
16 {
17 errno = ERROR_INVALID_HANDLE;
18 return -1;
19 }
20
21 long new_network_events = 0;
22 int delete_event = 0;
23 auto_ptr <ACE_Auto_Event> event;
24
25 // Look up the repository to see if the <event_handler> is already
26 // there.
27 ACE_Reactor_Mask old_masks;
28 int found = this->handler_rep_.modify_network_events_i (io_handle,
29 new_masks,
30 old_masks,
31 new_network_events,
32 event_handle,
33 delete_event,
34 ACE_Reactor::ADD_MASK);
35
36 // Check to see if the user passed us a valid event; If not then we
37 // need to create one
38 if (event_handle == ACE_INVALID_HANDLE)
39 {
40 // Note: don't change this since some C++ compilers have
41 // <auto_ptr>s that don't work properly
42 auto_ptr<ACE_Auto_Event> tmp (new ACE_Auto_Event);
43 event = tmp;
44 event_handle = event->handle ();
45 delete_event = 1;
46 }
47
48 int result = ::WSAEventSelect ((SOCKET) io_handle,
49 event_handle,
50 new_network_events);
鍙互鐪嬪埌鍦?2琛宑reate event,鍦?4澶嶅埗鍒癳vent_handle,鏈鍚庨氳繃WSAEventSelect灝嗚繖涓猧o_handle鍜宔vent_handle緇戝畾鍦ㄤ竴璧蜂簡
榪欎釜register_handle璋冪敤涓鑸兘鍦‥vent_Handler鐨刼pen鍑芥暟涓紝瀹炵幇浜嗘敞鍐屽埌Reactor涓幓銆?BR>
4. 絳夊緟浜嬩歡
濡備綍媯嫻嬪埌瑕佸彂鐢熺殑socket鐨勪簨浠跺憿錛熸瘮濡傛湁鏂扮殑client榪炴帴錛屾敹鍙戙侫CE騫朵笉鐩存帴璋冪敤select鍑芥暟鏉ュ彇寰椼?BR>ACE璋冪敤WaitForMultipleObjectsEx鏉ョ瓑寰呬簨浠剁殑鍙戠敓銆侫CE榪欐牱鍋氱殑濂藉鏄笉浣嗗彲浠ユ崟鎹塻ocket浜嬩歡錛屼篃鍙互鎹曟崏鍒板叾浠栦簨浠躲傚墠闈㈣榪囦簡姣忎竴涓搴旂殑socket閮芥湁涓涓猠vent_handle涓庝箣瀵瑰簲銆?STRONG>WaitForMultipleObjectsEx浼?xì)灏嗗彂鐢熶簨錃g鐨剆ocket handle鐨刬ndex榪斿洖銆傝繖鏍稟CE_Reactor灝卞彲浠ュ埄鐢ㄨ繖涓猻lot鏉ユ煡鍒癷o_handle鍜宔vent_handler( 娉ㄦ剰:event_handle鍜宔vent_handler鏄笉鍚岀殑)
2 ACE_WFMO_Reactor::wait_for_multiple_events (int timeout,
3 int alertable)
4 {
5 // Wait for any of handles_ to be active, or until timeout expires.
6 // If <alertable> is enabled allow asynchronous completion of
7 // ReadFile and WriteFile operations.
8
9 return ::WaitForMultipleObjectsEx (this->handler_rep_.max_handlep1 (),
10 this->handler_rep_.handles (),
11 FALSE,
12 timeout,
13 alertable);
14 }
5.鍒嗗彂浜嬩歡
鏍規(guī)嵁WaitForMultiObjectEx榪斿洖鐨剆lot灝卞彲浠ユ煡璇㈠埌event_handler鏉ヨ皟鐢ㄧ敤鎴風(fēng)殑澶勭悊鍑芥暟浜?BR>
2 ACE_WFMO_Reactor::complex_dispatch_handler (DWORD slot,
3 ACE_HANDLE event_handle)
4 {
5 // This dispatch is used for I/O entires.
6
7 ACE_WFMO_Reactor_Handler_Repository::Current_Info ¤t_info =
8 this->handler_rep_.current_info ()[slot];
9
10 WSANETWORKEVENTS events;
11 ACE_Reactor_Mask problems = ACE_Event_Handler::NULL_MASK;
12 if (::WSAEnumNetworkEvents ((SOCKET) current_info.io_handle_,
13 event_handle,
14 &events) == SOCKET_ERROR)
15 problems = ACE_Event_Handler::ALL_EVENTS_MASK;
16 else
17 {
18 // Prepare for upcalls. Clear the bits from <events> representing
19 // events the handler is not interested in. If there are any left,
20 // do the upcall(s). upcall will replace events.lNetworkEvents
21 // with bits representing any functions that requested a repeat
22 // callback before checking handles again. In this case, continue
23 // to call back unless the handler is unregistered as a result of
24 // one of the upcalls. The way this is written, the upcalls will
25 // keep being done even if one or more upcalls reported problems.
26 // In practice this may turn out not so good, but let's see. If any
27 // problems, please notify Steve Huston <shuston@riverace.com>
28 // before or after you change this code.
29 events.lNetworkEvents &= current_info.network_events_;
30 while (events.lNetworkEvents != 0)
31 {
32 ACE_Event_Handler *event_handler =
33 current_info.event_handler_;
34
35 int reference_counting_required =
36 event_handler->reference_counting_policy ().value () ==
37 ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
38
39 // Call add_reference() if needed.
40 if (reference_counting_required)
41 {
42 event_handler->add_reference ();
43 }
44
45 // Upcall
46 problems |= this->upcall (current_info.event_handler_,
47 current_info.io_handle_,
48 events);
49
50 // Call remove_reference() if needed.
51 if (reference_counting_required)
52 {
53 event_handler->remove_reference ();
54 }
55
56 if (this->handler_rep_.scheduled_for_deletion (slot))
57 break;
58 }
59 }
60
61 if (problems != ACE_Event_Handler::NULL_MASK
62 && !this->handler_rep_.scheduled_for_deletion (slot) )
63 this->handler_rep_.unbind (event_handle, problems);
64
65 return 0;
66 }
榪欓噷鍊煎緱娉ㄦ剰鐨勬槸ACE閫氳繃璋冪敤WSAEnumNetworkEvents鏉ラ噸緗甧vent_handle銆?BR>
璁茬殑姣旇緝姒傝錛屾洿鍏蜂綋鐨勭粏鑺傝鑷繁闃呰婧愮爜銆?BR>鍏充簬ACE_Reactor鐨勭敤娉曡鍙傝鍓嶄竴綃囨垜鐨勭ず渚嬨?BR>
]]>
涓ょ瀹炵幇鏂規(guī)硶
1.Per client Per Thread (姣忎釜榪炴帴姣忎釜綰跨▼鏉ュ鐞?
榪欑鏂瑰紡姣旇緝綆鍗曪紝鏄撲簬瀹炵幇銆傜己鐐規(guī)槸濡傛灉鏈夊ぇ閲忕殑榪炴帴錛屽繀鐒跺崰鐢ㄨ繃閲忕殑緋葷粺璧勬簮銆?BR>
浠g爜:
#pragma comment(lib,"ACED.lib")
#else
#pragma comment(lib,"ACE.lib")
#endif
#include <ace/OS_main.h>
#include <ace/ACE.h>
#include <ace/Log_Msg.h>
#include <ace/SOCK_Acceptor.h>
#include <ace/Thread.h>
DWORD worker(void *arg)
{
ACE_SOCK_Stream *pStream =(ACE_SOCK_Stream *) arg;
char buffer[32] = {0};
int len;
while( (len = pStream->recv(buffer,sizeof(buffer)-1)) >0)
{
if(pStream->send_n(buffer,len)<=0)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("send failed")));
break;
}
}
ACE_INET_Addr raddr;
pStream->get_remote_addr(raddr);
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%P|%t) close:%s %d\n"),raddr.get_host_addr(),raddr.get_port_number()));
pStream->close();
delete pStream;
return 0;
}
int main(int argc, char *argv[])
{
ACE_INET_Addr addr(1500);
ACE_SOCK_Acceptor server;
if(server.open(addr)==-1)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("bind failed")));
return 1;
}
ACE_SOCK_Stream *pStream = 0;
while((pStream =new ACE_SOCK_Stream()) && server.accept(*pStream)!=-1)
{
ACE_INET_Addr raddr;
pStream->get_remote_addr(raddr);
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%P|%t) connect:%s %d\n"),raddr.get_host_addr(),raddr.get_port_number()));
ACE_Thread::spawn(worker,pStream);
}
server.close();
return 0;
}
璇存槑:
ACE_Thread鐢ㄦ潵鍚姩thread錛屽綋鏈塩lient榪炰笂鏉ョ殑鏃跺欙紝鍚姩worker thread鏉ュ鐞嗐?BR>
2.浜嬩歡妯″瀷
socket閲岄潰鏄湁select鏈哄埗錛孉CE涔熸彁渚涗簡榪欑鏂瑰紡銆?BR>姒傚康:
Event_Handler:鏈変簨浠舵潵涓寸殑鏃跺欑殑澶勭悊鍣?BR>Reactor:浜嬩歡綆$悊錛岃礋璐g鐞咵vent_Hanlde鍜屽垎鍙戜簨浠?BR>Acceptor璐熻矗榪炴帴Event_Handle,Reactor鍜孲ock_Acceptor
浠g爜:
#pragma comment(lib,"ACED.lib")
#else
#pragma comment(lib,"ACE.lib")
#endif
#include <ace/OS_main.h>
#include <ace/ACE.h>
#include <ace/Svc_Handler.h>
#include <ace/Acceptor.h>
#include <ace/Log_Msg.h>
#include <ace/SOCK_Acceptor.h>
#include <ace/Thread.h>
class My_Svc_Handler:
public ACE_Svc_Handler <ACE_SOCK_STREAM,ACE_NULL_SYNCH>
{
public:
int open(void*)
{
ACE_INET_Addr raddr;
peer().get_remote_addr(raddr);
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%P|%t) connect:%s %d %d\n"),raddr.get_host_addr(),raddr.get_port_number(),this));
reactor()->register_handler(this,ACE_Event_Handler::READ_MASK);
return 0;
}
int handle_input(ACE_HANDLE)
{
char buffer[32] = {0};
int len = peer().recv(buffer,sizeof(buffer)-1);
if(len>0)
{
if(peer().send_n(buffer,len)<=0)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("send failed")));
return -1; //must return -1 to call handle_close
}
return 0;
}
else
{
return -1; //must return -1 to call handle_close
}
}
int handle_close(ACE_HANDLE handle,ACE_Reactor_Mask close_mask)
{
ACE_INET_Addr raddr;
peer().get_remote_addr(raddr);
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("(%P|%t) close:%s %d\n"),raddr.get_host_addr(),raddr.get_port_number()));
peer().close();
return 0;
}
};
typedef ACE_Acceptor<My_Svc_Handler,ACE_SOCK_ACCEPTOR> MyAcceptor;
int main(int argc, char *argv[])
{
ACE_INET_Addr addr(1500);
MyAcceptor server;
if(server.open(addr)==-1)
{
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%P|%t) %p\n"),
ACE_TEXT ("bind failed")));
return 1;
}
while(1){
ACE_Reactor::instance()->handle_events();
}
server.close();
return 0;
}
璇存槑錛?BR>1.浣跨敤ACE_Acceptor妯℃澘綾繪潵瀹氫箟鑷繁鐨凙cceptor
2.ACE_Reactor::instance()->handle_events()鏉ュ疄鐜頒簨浠跺垎鍙?BR>3.鍦‥vent_Handle閲岄潰浣跨敤reactor()->register_handler(this,ACE_Event_Handler::READ_MASK);鏉ユ敞鍐岃鍏沖績鐨勪簨浠?BR>4.鍦‥vent_Handle涓嬌鐢╬eer()鏉ヨ幏寰桽ock_Stream鏉ュ彂閫佹帴鍙楁暟鎹?BR>
]]>
]]>
2.build ACE in Visual Studio,generate ACE.lib(dll)[for release] & ACEd.lib(dll)[for debug]
3.create a empty project named: ACETest
4.add ACE path into Project Include Path and add ACE/lib into project lib path
5.create a file(hello.cpp)
6.build & execute