00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012 #ifndef _TCP_SOCK_CONNECTOR_
00013 #define _TCP_SOCK_CONNECTOR_
00014
00015
00016 #include "ace/SOCK_Acceptor.h"
00017 #include "ace/SOCK_Connector.h"
00018 #include "ace/SOCK_Stream.h"
00019 #include "ace/INET_Addr.h"
00020
00021 #include "ace/Acceptor.h"
00022 #include "ace/Connector.h"
00023 #include "ace/Svc_Handler.h"
00024
00025 #include "ace/CDR_Stream.h"
00026 #include "ace/Message_Block.h"
00027
00028 #include "ace/Task.h"
00029 #include "ace/Thread_Manager.h"
00030 #include "ace/Thread_Mutex.h"
00031 #include "ace/Thread_Semaphore.h"
00032 #include "ace/Get_Opt.h"
00033 #include "ace/Reactor.h"
00034 #include "ace/Service_Object.h"
00035 #include "ace/Signal.h"
00036 #include "ace/Handle_Set.h"
00037 #include "ace/FILE_Addr.h"
00038 #include "ace/OS.h"
00039 #include "ace/os_include/os_netdb.h"
00040 #include "ace/Log_Msg.h"
00041 #include "ace/Synch_Options.h"
00042
00043
00044 #include <BaseDef.h>
00045
00046
00047 #include <iostream>
00048 #include <sstream>
00049 #include <string>
00050 #include <sstream>
00051 #include <vector>
00052 #include <algorithm>
00053 #include <netinet/in.h>
00054
00059 namespace channel {
00060
00061 class ConnInfo;
00062 template <class, class> class ConnHandler;
00063 template <class, class> class Connector;
00064 template <class> class TcpSockTransport;
00065
00066 u_short UNDEFINED_TCP_PORT=0;
00067 u_short DEFAULT_TCP_PORT=3456;
00068
00071 template <class Channel>
00072 class Tcp_ConnHandler
00073 : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>,
00074 public ConnHandler<Channel, TcpSockTransport<Channel> > {
00075 public:
00076 typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> PARENT;
00077 Tcp_ConnHandler () {}
00078 virtual int open (void *)
00079 {
00080 ACE_DEBUG ((LM_DEBUG, "a new tcp conn comes up...\n"));
00081
00082 int bufsiz = ACE_DEFAULT_MAX_SOCKET_BUFSIZ;
00083 peer ().set_option (SOL_SOCKET, SO_SNDBUF,
00084 &bufsiz, sizeof bufsiz);
00085
00086 return activate (THR_NEW_LWP | THR_DETACHED);
00087 }
00088 virtual int close(u_long flag=0)
00089 {
00090 ACE_UNUSED_ARG(flag);
00091 ACE_DEBUG ((LM_DEBUG, "(%t) Tcp_ConnHandler<Channel>::close\n"));
00092 if(this->cm_ != NULL && this->cm_->exit_start_) {
00093 ACE_DEBUG ((LM_DEBUG, "(%t) Tcp_ConnHandler<Channel>::close: release exit_sema_\n"));
00094
00095 this->cm_->exit_sema_.release();
00096
00097 PARENT::close();
00098 }
00099 return 0;
00100 }
00101 virtual void shut_down(void) {
00102
00103
00104 ACE_DEBUG((LM_DEBUG,"one tcp socket close...\n"));
00105 ACE_OS::closesocket(get_handle());
00106
00107 }
00108 virtual ACE_SOCK_Stream &peer_stream(void) {
00109 return (ACE_SOCK_Stream &) ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>::peer();
00110 }
00111 virtual int svc (void)
00112 {
00113 return ConnHandler<Channel, TcpSockTransport<Channel> >::service();
00114 }
00115 };
00116
00118 template <class Channel>
00119 class Tcp_Acceptor
00120 : public ACE_Acceptor<Tcp_ConnHandler<Channel>, ACE_SOCK_Acceptor> {
00121 public:
00122 typedef ACE_Acceptor<Tcp_ConnHandler<Channel>, ACE_SOCK_Acceptor>
00123 PARENT;
00124
00125 Connector<Channel, TcpSockTransport<Channel> > *cm_;
00126 virtual int activate_svc_handler (Tcp_ConnHandler<Channel> *sh)
00127 {
00128
00129 sh->set_up (cm_, PASSIVE_ROLE);
00130
00131 if(PARENT::activate_svc_handler(sh)==-1) return -1;
00132 return 0;
00133 }
00134
00135
00136 };
00137
00139 template <class Channel>
00140 class Tcp_Connector
00141 : public ACE_Connector<Tcp_ConnHandler<Channel>, ACE_SOCK_Connector> {
00142 public:
00143 typedef ACE_Connector<Tcp_ConnHandler<Channel>, ACE_SOCK_Connector>
00144 PARENT;
00145
00146 Connector<Channel, TcpSockTransport<Channel> > *cm_;
00147 virtual int activate_svc_handler (Tcp_ConnHandler<Channel> *sh)
00148 {
00149
00150 sh->set_up (cm_, ACTIVE_ROLE);
00151
00152 if(PARENT::activate_svc_handler(sh)==-1) return -1;
00153 return 0;
00154 }
00155
00156
00157 };
00158
00160 template <class Channel>
00161 class TcpSockTransport {
00162 typedef ConnHandler<Channel, TcpSockTransport<Channel> > ConnHandler;
00163 typedef Connector<Channel, TcpSockTransport<Channel> > Connector;
00164 private:
00165
00166
00167 std::string host_addr_;
00168 u_short port_;
00169
00170 Tcp_Acceptor<Channel> tcp_acceptor_;
00171
00172 Tcp_Connector<Channel> tcp_connector_;
00173
00174 public:
00175
00176 typedef TcpSockTransport<Channel> TransportType;
00177
00178 TcpSockTransport(Connector *c) {
00179 port_ = UNDEFINED_TCP_PORT;
00180
00181 tcp_acceptor_.cm_ = c;
00182 tcp_connector_.cm_ = c;
00183 }
00184 static Interface_Type type(void) { return INET_SOCK; }
00185
00186
00187 std::string host_addr(void) { return host_addr_; }
00188 int port(void) { return port_;}
00189
00191 Status get_my_ip(std::string &addr) {
00192 struct hostent *host_info;
00193 ACE_utsname host_data;
00194 if (ACE_OS::uname (&host_data) < 0)
00195 return FAILURE;
00196 if ((host_info = ACE_OS::gethostbyname (ACE_TEXT_ALWAYS_CHAR(host_data.nodename))) == NULL)
00197 return FAILURE;
00198 long host,host_addr;
00199 ACE_OS::memcpy ((char *) &host,
00200 (char *) host_info->h_addr,
00201 host_info->h_length);
00202 host_addr = ntohl(host);
00203 ACE_DEBUG ((LM_DEBUG, "my name =[%s] my addr=[%ld]\n", host_data.nodename, host_addr));
00204 ACE_INET_Addr inaddr(1234,host_addr);
00205 addr = inaddr.get_host_addr();
00206 ACE_DEBUG ((LM_DEBUG, "my_addr=[%s]\n",addr.c_str()));
00207 return SUCCESS;
00208 }
00209
00211 Status get_map_index(ConnInfo &addr)
00212 {
00213 std::string addr_index;
00214 ACE_INET_Addr inaddr(addr.port(), addr.ip().c_str());
00215 if(std::string(addr.get_host_addr()).find(ACE_LOCALHOST)!=std::string::npos) {
00216 if (get_my_ip(addr_index) != SUCCESS)
00217 return FAILURE;
00218 }
00219 else
00220 addr_index = inaddr.get_host_addr();
00221 addr.set_host_addr (addr_index.c_str());
00222 return SUCCESS;
00223 }
00224
00226 Status open(ConnInfo ci)
00227 {
00228 port_ = ci.port();
00229
00230 ACE_DEBUG ((LM_DEBUG, "============= My Info ==============\n"));
00231
00232 if(port_ != UNDEFINED_TCP_PORT) {
00233 ACE_INET_Addr addr(port_, INADDR_ANY);
00234 ACE_DEBUG ((LM_DEBUG, "port=%d host_name=%s\n",port_, addr.get_host_name()));
00235
00236 if (get_my_ip(host_addr_) != SUCCESS)
00237 return FAILURE;
00238
00239 if(tcp_acceptor_.open(addr) == -1) {
00240 ACE_DEBUG ((LM_DEBUG, "fail to open tcp lsitening sock...\n"));
00241 return FAILURE;
00242 }
00243 }
00244 ACE_DEBUG ((LM_DEBUG, "=================================\n"));
00245 return SUCCESS;
00246 }
00247
00248 Status close(void)
00249 {
00250 if(port_ != UNDEFINED_TCP_PORT)
00251 tcp_acceptor_.close();
00252 return SUCCESS;
00253 }
00254
00256 Status connect(ConnInfo addr, ConnHandler *&conn_handler)
00257 {
00258 ACE_DEBUG ((LM_DEBUG, "TcpSockTransport<Channel>::connect...\n"));
00259
00260 addr.dump();
00261 ACE_INET_Addr inaddr(addr.port(), addr.ip().c_str());
00262
00263 Tcp_ConnHandler<Channel> *handler=NULL;
00264 handler = new Tcp_ConnHandler<Channel>();
00265 if(tcp_connector_.connect(handler, inaddr, ACE_Synch_Options::synch) == -1)
00266 if (errno != EWOULDBLOCK) {
00267 ACE_DEBUG ((LM_DEBUG, " !!! server %s | %d is DOWN !!!\n", inaddr.get_host_addr(), inaddr.get_port_number()));
00268 delete handler;
00269 return FAILURE;
00270 }
00271 conn_handler = handler;
00272 ACE_DEBUG ((LM_DEBUG, "TcpSockTransport<Channel>::connect...finish...\n"));
00273 return SUCCESS;
00274 }
00275 Status disconnect(ConnInfo addr) {
00276 ACE_UNUSED_ARG(addr);
00277 return SUCCESS; }
00278
00279 };
00280
00281 };
00282
00283 #endif
00284