Sleipnir
|
00001 /***************************************************************************** 00002 * This file is provided under the Creative Commons Attribution 3.0 license. 00003 * 00004 * You are free to share, copy, distribute, transmit, or adapt this work 00005 * PROVIDED THAT you attribute the work to the authors listed below. 00006 * For more information, please see the following web page: 00007 * http://creativecommons.org/licenses/by/3.0/ 00008 * 00009 * This file is a component of the Sleipnir library for functional genomics, 00010 * authored by: 00011 * Curtis Huttenhower (chuttenh@princeton.edu) 00012 * Mark Schroeder 00013 * Maria D. Chikina 00014 * Olga G. Troyanskaya (ogt@princeton.edu, primary contact) 00015 * 00016 * If you use this library, the included executable tools, or any related 00017 * code in your work, please cite the following publication: 00018 * Curtis Huttenhower, Mark Schroeder, Maria D. Chikina, and 00019 * Olga G. Troyanskaya. 00020 * "The Sleipnir library for computational functional genomics" 00021 *****************************************************************************/ 00022 #include "stdafx.h" 00023 #include "server.h" 00024 #include "serverclient.h" 00025 00026 namespace Sleipnir { 00027 00028 CServer* CServerImpl::s_pServer = NULL; 00029 const char* CServerImpl::c_szPort = "port"; 00030 const char* CServerImpl::c_szTimeout = "timeout"; 00031 00059 bool CServer::Initialize( size_t iPort, size_t iTimeout, IServerClient* pServerClient ) { 00060 #ifndef _MSC_VER 00061 struct sigaction Sigact; 00062 #endif // _MSC_VER 00063 00064 m_pClient = pServerClient; 00065 m_iPort = iPort; 00066 m_iTimeout = iTimeout; 00067 #ifndef _MSC_VER 00068 Sigact.sa_handler = Alarm; 00069 memset( &Sigact.sa_mask, 0, sizeof(Sigact.sa_mask) ); 00070 Sigact.sa_flags = 0; 00071 sigaction( SIGALRM, &Sigact, NULL ); 00072 #endif // _MSC_VER 00073 00074 return true; } 00075 00076 #ifndef _MSC_VER 00077 void CServerImpl::Alarm( int iSig ) { } 00078 #endif // _MSC_VER 00079 00096 bool CServer::Start( ) { 00097 sockaddr_in Addr; 00098 char cOn; 00099 00100 #ifdef _MSC_VER 00101 WSADATA sWSA; 00102 WSAStartup( MAKEWORD(2, 0), &sWSA ); 00103 #endif // _MSC_VER 00104 00105 m_fStop = false; 00106 m_iSocket = socket( PF_INET, SOCK_STREAM, 0 ); 00107 cOn = true; 00108 setsockopt( m_iSocket, SOL_SOCKET, SO_REUSEADDR, &cOn, sizeof(cOn) ); 00109 00110 Addr.sin_family = AF_INET; 00111 Addr.sin_port = htons( m_iPort ); 00112 Addr.sin_addr.s_addr = INADDR_ANY; 00113 s_pServer = this; 00114 if( bind( m_iSocket, (const sockaddr*)&Addr, sizeof(Addr) ) || 00115 listen( m_iSocket, INT_MAX ) ) { 00116 #ifdef _MSC_VER 00117 { 00118 char acError[ 1024 ]; 00119 00120 strerror_s( acError, ARRAYSIZE(acError) - 1, errno ); 00121 g_CatSleipnir( ).error( "CServer::Start( ) bind failed: %s", acError ); 00122 } 00123 #else // _MSC_VER 00124 g_CatSleipnir( ).error( "CServer::Start( ) bind failed: %s", strerror( errno ) ); 00125 #endif // _MSC_VER 00126 return false; } 00127 00128 g_CatSleipnir( ).notice( "CServer::Start( ) bound to port %d", m_iPort ); 00129 Listen( ); 00130 g_CatSleipnir( ).info( "CServer::Start( ) preparing to shutdown..." ); 00131 00132 #ifdef _MSC_VER 00133 WSACleanup( ); 00134 #endif // _MSC_VER 00135 00136 return true; } 00137 00138 void CServerImpl::Listen( ) { 00139 SOCKET iClient; 00140 socklen_t iSize; 00141 CServerClientImpl* pClient; 00142 pthread_t thrdClient; 00143 sockaddr_in Addr; 00144 #ifndef _MSC_VER 00145 itimerval Time; 00146 00147 memset( &Time, 0, sizeof(Time) ); 00148 #endif // _MSC_VER 00149 while( !m_fStop ) { 00150 #ifndef _MSC_VER 00151 Time.it_value.tv_usec = 1000 * m_iTimeout; 00152 setitimer( ITIMER_REAL, &Time, NULL ); 00153 Time.it_value.tv_usec = 0; 00154 #endif // _MSC_VER 00155 iSize = sizeof(Addr); 00156 if( ( iClient = accept( m_iSocket, (sockaddr*)&Addr, &iSize ) ) == -1 ) 00157 continue; 00158 #ifndef _MSC_VER 00159 setitimer( ITIMER_REAL, &Time, NULL ); 00160 #endif // _MSC_VER 00161 00162 pClient = new CServerClientImpl( iClient, m_pClient->NewInstance( iClient, 00163 iSize = ntohl( Addr.sin_addr.s_addr ), ntohs( Addr.sin_port ) ) ); 00164 g_CatSleipnir( ).info( "CServer::Listen( ) client 0x%08x connected from %d.%d.%d.%d", 00165 pClient, ( iSize >> 24 ) & 0xFF, ( iSize >> 16 ) & 0xFF, ( iSize >> 8 ) & 0xFF, 00166 iSize & 0xFF ); 00167 pthread_create( &thrdClient, NULL, CServerClientImpl::StartRoutine, pClient ); 00168 pthread_detach( thrdClient ); } } 00169 00170 }