⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpendpoint.cc

📁 编译工具
💻 CC
字号:
// -*- Mode: C++; -*-//                            Package   : omniORB// tcpEndpoint.cc             Created on: 19 Mar 2001//                            Author    : Sai Lai Lo (sll)////    Copyright (C) 2001 AT&T Laboratories Cambridge////    This file is part of the omniORB library////    The omniORB library is free software; you can redistribute it and/or//    modify it under the terms of the GNU Library General Public//    License as published by the Free Software Foundation; either//    version 2 of the License, or (at your option) any later version.////    This library is distributed in the hope that it will be useful,//    but WITHOUT ANY WARRANTY; without even the implied warranty of//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU//    Library General Public License for more details.////    You should have received a copy of the GNU Library General Public//    License along with this library; if not, write to the Free//    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA//    02111-1307, USA////// Description://	*** PROPRIETORY INTERFACE ***///*  $Log: tcpEndpoint.cc,v $  Revision 1.1.2.25  2004/10/18 11:46:47  dgrisby  accept() error handling didn't work on MacOS X.  Revision 1.1.2.24  2004/10/17 22:27:23  dgrisby  Handle errors in accept() properly. Thanks Kamaldeep Singh Khanuja and  Jeremy Van Grinsven.  Revision 1.1.2.23  2004/10/17 20:14:33  dgrisby  Updated support for OpenVMS. Many thanks to Bruce Visscher.  Revision 1.1.2.22  2003/11/12 16:04:17  dgrisby  Set sockets to close on exec.  Revision 1.1.2.21  2003/07/25 16:04:57  dgrisby  vxWorks patches.  Revision 1.1.2.20  2003/05/04 11:22:14  dgrisby  Set the poked flag in the right place.  Revision 1.1.2.19  2003/05/02 09:58:13  dgrisby  Ensure shutdown happens even if the TCP stack has broken.  Revision 1.1.2.18  2003/02/17 02:03:10  dgrisby  vxWorks port. (Thanks Michael Sturm / Acterna Eningen GmbH).  Revision 1.1.2.17  2003/01/06 11:11:55  dgrisby  New AddrInfo instead of gethostbyname.  Revision 1.1.2.16  2002/10/04 11:11:46  dgrisby  Transport fixes: ENOTSOCK for Windows, SOMAXCONN in listen().  Revision 1.1.2.15  2002/08/27 10:32:27  dgrisby  FreeBSD fixes.  Revision 1.1.2.14  2002/08/16 16:00:55  dgrisby  Bugs accessing uninitialised String_vars with [].  Revision 1.1.2.13  2002/05/07 12:54:44  dgrisby  Fix inevitable Windows header brokenness.  Revision 1.1.2.12  2002/05/07 00:46:26  dgrisby  Different define for TCP protocol number.  Revision 1.1.2.11  2002/05/07 00:28:32  dgrisby  Turn off Nagle's algorithm. Fixes odd Linux loopback behaviour.  Revision 1.1.2.10  2002/04/29 11:52:51  dgrisby  More fixes for FreeBSD, Darwin, Windows.  Revision 1.1.2.9  2002/03/19 15:42:04  dpg1  Use list of IP addresses to pick a non-loopback interface if there is one.  Revision 1.1.2.8  2002/03/13 16:05:40  dpg1  Transport shutdown fixes. Reference count SocketCollections to avoid  connections using them after they are deleted. Properly close  connections when in thread pool mode.  Revision 1.1.2.7  2002/03/11 12:24:39  dpg1  Restrict bind to specified host, if any.  Revision 1.1.2.6  2001/07/31 16:16:17  sll  New transport interface to support the monitoring of active connections.  Revision 1.1.2.5  2001/07/13 15:34:24  sll  Added the ability to monitor connections and callback to the giopServer when  data has arrived at a connection.  Revision 1.1.2.4  2001/06/20 18:35:15  sll  Upper case send,recv,connect,shutdown to avoid silly substutition by  macros defined in socket.h to rename these socket functions  to something else.  Revision 1.1.2.3  2001/06/13 20:13:49  sll  Minor updates to make the ORB compiles with MSVC++.  Revision 1.1.2.2  2001/05/01 16:04:42  sll  Silly use of sizeof() on const char*. Should use strlen().  Revision 1.1.2.1  2001/04/18 18:10:43  sll  Big checkin with the brand new internal APIs.*/#include <omniORB4/CORBA.h>#include <omniORB4/giopEndpoint.h>#include <SocketCollection.h>#include <tcp/tcpConnection.h>#include <tcp/tcpAddress.h>#include <tcp/tcpEndpoint.h>#include <stdio.h>#include <omniORB4/linkHacks.h>OMNI_EXPORT_LINK_FORCE_SYMBOL(tcpEndpoint);OMNI_NAMESPACE_BEGIN(omni)/////////////////////////////////////////////////////////////////////////tcpEndpoint::tcpEndpoint(const IIOP::Address& address) :  pd_socket(RC_INVALID_SOCKET), pd_address(address),  pd_new_conn_socket(RC_INVALID_SOCKET), pd_callback_func(0),  pd_callback_cookie(0), pd_poked(0) {  pd_address_string = (const char*) "giop:tcp:255.255.255.255:65535";  // address string is not valid until bind is called.}/////////////////////////////////////////////////////////////////////////tcpEndpoint::tcpEndpoint(const char* address) :  pd_socket(RC_INVALID_SOCKET),  pd_new_conn_socket(RC_INVALID_SOCKET), pd_callback_func(0),  pd_callback_cookie(0) {  pd_address_string = address;  // OMNIORB_ASSERT(strncmp(address,"giop:tcp:",9) == 0);  const char* host = strchr(address,':');  host = strchr(host+1,':') + 1;  const char* port = strchr(host,':') + 1;  CORBA::ULong hostlen = port - host - 1;  // OMNIORB_ASSERT(hostlen);  pd_address.host = CORBA::string_alloc(hostlen);  strncpy(pd_address.host,host,hostlen);  ((char*)pd_address.host)[hostlen] = '\0';  int rc;  unsigned int v;  rc = sscanf(port,"%u",&v);  // OMNIORB_ASSERT(rc == 1);  // OMNIORB_ASSERT(v > 0 && v < 65536);  pd_address.port = v;}/////////////////////////////////////////////////////////////////////////tcpEndpoint::~tcpEndpoint() {  if (pd_socket != RC_INVALID_SOCKET) {    CLOSESOCKET(pd_socket);    pd_socket = RC_INVALID_SOCKET;  }}/////////////////////////////////////////////////////////////////////////const char*tcpEndpoint::type() const {  return "giop:tcp";}/////////////////////////////////////////////////////////////////////////const char*tcpEndpoint::address() const {  return pd_address_string;}/////////////////////////////////////////////////////////////////////////CORBA::BooleantcpEndpoint::Bind() {  OMNIORB_ASSERT(pd_socket == RC_INVALID_SOCKET);  if ((pd_socket = socket(INETSOCKET,SOCK_STREAM,0)) == RC_INVALID_SOCKET) {    return 0;  }  {    // Prevent Nagle's algorithm    int valtrue = 1;    if (setsockopt(pd_socket,IPPROTO_TCP,TCP_NODELAY,		   (char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR) {      CLOSESOCKET(pd_socket);      pd_socket = RC_INVALID_SOCKET;      return 0;    }  }  SocketSetCloseOnExec(pd_socket);  const char* host;  if ((char*)pd_address.host && strlen(pd_address.host) != 0) {    if (omniORB::trace(25)) {      omniORB::logger log;      log << "Explicit bind to host " << pd_address.host << ".\n";    }    host = pd_address.host;  }  else {    host = 0;  }  LibcWrapper::AddrInfo_var ai;  ai = LibcWrapper::getAddrInfo(host, pd_address.port);  if ((LibcWrapper::AddrInfo*)ai == 0) {    if (omniORB::trace(1)) {      omniORB::logger log;      log << "Cannot get the address of host " << host << ".\n";    }    CLOSESOCKET(pd_socket);    return 0;  }  if (pd_address.port) {    int valtrue = 1;    if (setsockopt(pd_socket,SOL_SOCKET,SO_REUSEADDR,		   (char*)&valtrue,sizeof(int)) == RC_SOCKET_ERROR) {      CLOSESOCKET(pd_socket);      pd_socket = RC_INVALID_SOCKET;      return 0;    }  }  if (omniORB::trace(25)) {    omniORB::logger l;    CORBA::String_var addr(ai->asString());    l << "Bind to address " << addr << ".\n";  }  if (::bind(pd_socket, ai->addr(), ai->addrSize()) == RC_SOCKET_ERROR) {    CLOSESOCKET(pd_socket);    return 0;  }  if (listen(pd_socket,SOMAXCONN) == RC_SOCKET_ERROR) {    CLOSESOCKET(pd_socket);    return 0;  }  // Now figure out the details to put in IORs  struct sockaddr_in addr;  SOCKNAME_SIZE_T l;  l = sizeof(struct sockaddr_in);  if (getsockname(pd_socket,		  (struct sockaddr *)&addr,&l) == RC_SOCKET_ERROR) {    CLOSESOCKET(pd_socket);    return 0;  }  pd_address.port = ntohs(addr.sin_port);  if (!(char*)pd_address.host || strlen(pd_address.host) == 0) {    // Try to find the first interface that isn't the loopback    const omnivector<const char*>* ifaddrs      = giopTransportImpl::getInterfaceAddress("giop:tcp");    if (ifaddrs && !ifaddrs->empty()) {      // TCP transport successfully gave us a list of interface addresses      omnivector<const char*>::const_iterator i;      for (i = ifaddrs->begin(); i != ifaddrs->end(); i++) {	if (strcmp(*i, "127.0.0.1"))	  break;      }      if (i == ifaddrs->end()) {	// Only interface was the loopback -- we'll have to use that	i = ifaddrs->begin();      }      pd_address.host = CORBA::string_dup(*i);    }    else {      omniORB::logs(5, "No list of interface addresses; fall back to "		    "system hostname.");      char self[64];      if (gethostname(&self[0],64) == RC_SOCKET_ERROR) {	omniORB::logs(1, "Cannot get the name of this host.");	CLOSESOCKET(pd_socket);	return 0;      }      if (omniORB::trace(10)) {	omniORB::logger l;	l << "My hostname is " << self << ".\n";      }      LibcWrapper::AddrInfo_var ai;      ai = LibcWrapper::getAddrInfo(self, pd_address.port);      if ((LibcWrapper::AddrInfo*)ai == 0) {	if (omniORB::trace(1)) {	  omniORB::logger log;	  log << "Cannot get the address of my hostname " << self << ".\n";	}	CLOSESOCKET(pd_socket);	return 0;      }      pd_address.host = ai->asString();    }  }  if (omniORB::trace(1) && strcmp(pd_address.host,"127.0.0.1") == 0) {    omniORB::logger log;    log << "Warning: the local loop back interface (127.0.0.1) is used as\n"	<< "this server's address. Only clients on this machine can talk to\n"	<< "this server.\n";  }  const char* format = "giop:tcp:%s:%d";  pd_address_string = CORBA::string_alloc(strlen(pd_address.host) +					  strlen(format)+6);  sprintf((char*)pd_address_string,format,	  (const char*)pd_address.host,(int)pd_address.port);  return 1;}/////////////////////////////////////////////////////////////////////////voidtcpEndpoint::Poke() {  tcpAddress* target = new tcpAddress(pd_address);  giopActiveConnection* conn;  if ((conn = target->Connect()) == 0) {    if (omniORB::trace(5)) {      omniORB::logger log;      log << "Warning: fail to connect to myself ("	  << (const char*) pd_address_string << ") via tcp.\n";    }    pd_poked = 1;  }  else {    delete conn;  }  delete target;}/////////////////////////////////////////////////////////////////////////voidtcpEndpoint::Shutdown() {  SHUTDOWNSOCKET(pd_socket);  decrRefCount();  omniORB::logs(20, "TCP endpoint shut down.");}/////////////////////////////////////////////////////////////////////////giopConnection*tcpEndpoint::AcceptAndMonitor(giopConnection::notifyReadable_t func,			      void* cookie) {  OMNIORB_ASSERT(pd_socket != RC_INVALID_SOCKET);  pd_callback_func = func;  pd_callback_cookie = cookie;  setSelectable(pd_socket,1,0,0);  while (1) {    pd_new_conn_socket = RC_INVALID_SOCKET;    if (!Select()) break;    if (pd_new_conn_socket != RC_INVALID_SOCKET) {      return  new tcpConnection(pd_new_conn_socket,this);    }    if (pd_poked)      return 0;  }  return 0;}/////////////////////////////////////////////////////////////////////////CORBA::BooleantcpEndpoint::notifyReadable(SocketHandle_t fd) {  if (fd == pd_socket) {    // New connection    SocketHandle_t sock;again:    sock = ::accept(pd_socket,0,0);    if (sock == RC_SOCKET_ERROR) {      if (ERRNO == RC_EBADF) {        omniORB::logs(20, "accept() returned EBADF, unable to continue");        return 0;      }      else if (ERRNO == RC_EINTR) {        omniORB::logs(20, "accept() returned EINTR, trying again");        goto again;      }#ifdef UnixArchitecture      else if (ERRNO == RC_EAGAIN) {        omniORB::logs(20, "accept() returned EAGAIN, trying again");        goto again;      }#endif      if (omniORB::trace(20)) {        omniORB::logger log;        log << "accept() failed with unknown error " << ERRNO << "\n";      }    }    else {#if defined(__vxWorks__)      // vxWorks "forgets" socket options      static const int valtrue = 1;      if(setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,		    (char*)&valtrue, sizeof(valtrue)) == ERROR) {	return 0;      }#endif      pd_new_conn_socket = sock;    }    setSelectable(pd_socket,1,0,1);    return 1;  }  else {    // Existing connection    SocketLink* conn = findSocket(fd,1);    if (conn) {      pd_callback_func(pd_callback_cookie,(tcpConnection*)conn);    }    return 1;  }}OMNI_NAMESPACE_END(omni)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -