Főoldal | Névtérlista | Osztályhierarchia | Betűrendes lista | Adatszerkezetek | Könyvtárak | Fájllista | Névtértagok | Adatmezők | Globális elemek

ListenServer.cpp

Ugrás a fájl dokumentációjához.
00001 /*
00002     mySocket, ListenServer
00003     Copyright (C) 2006  Kornel Csernai <csko@csko.hu>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00018 */
00019 #include <sys/param.h> // MAXHOSTNAMELEN
00020 #include <ListenServer.h>
00021 #include <SocketHandler.h>
00022 #include <IncomingSocket.h>
00023 #include <StringLib.h>
00024 
00025 using namespace std;
00026 using namespace StringLib;
00027 
00028 // Constructor
00029 ListenServer::ListenServer() : Socket(-1) {
00030 
00031   running = false;
00032   port = -1;
00033   addr = "";
00034 
00035   }
00036 
00037 // Destructor
00038 ListenServer::~ListenServer() {
00039 
00040   }
00041 
00042 // Try to socket(), bind(), listen()
00043 void ListenServer::Start(int _port, string _addr, SocketType _type){
00044 
00045   if(_type != TYPE_TCP) throw 0; // only TCP supported, yet
00046   type = _type;
00047 
00048   if(running) throw SocketException(ALREADY_RUNNING);
00049 
00050   try{
00051 
00052     Bind(_addr, _port);
00053     Listen(backlog);
00054 
00055     }
00056 
00057   catch(SocketException e) { // needs to be replaced
00058 
00059     switch(e.i){
00060       case SOCKET_FAILED:
00061         error("Socket failed: " + GetLastError());
00062         break;
00063       case BIND_FAILED:
00064         error("Bind failed: " + GetLastError());
00065         break;
00066       case LISTEN_FAILED:
00067         error("Listen failed: " + GetLastError());
00068         break;
00069       default:
00070         error("Unknown Exception!");
00071       }
00072     return;
00073 
00074     }
00075 
00076   SocketHandler* handler = SocketHandler::getInstance();
00077   if(!handler) throw SocketException(SOCKETHANDLING_FAILED);
00078 
00079   handler -> Add(this);
00080   port = _port;
00081   addr = _addr;
00082   running = true;
00083 
00084   debug("Starting listening on " + GetAddr() + ":" + itos(GetPort()));
00085   
00086   }
00087 
00088 // Another way to start  
00089 void ListenServer::Start(sockaddr_in _saddr, SocketType _type){
00090 
00091   Start(ntohs(_saddr.sin_port), (string) inet_ntoa(_saddr.sin_addr), _type);
00092 
00093   }
00094 
00095 void ListenServer::Stop(){
00096 
00097   if(!running) throw SocketException(NOT_RUNNING);
00098 
00099   SocketHandler* handler = SocketHandler::getInstance();
00100   if(!handler) throw SocketException(SOCKETHANDLING_FAILED);
00101 
00102   IncomingSocket* incoming;
00103 
00104   for(int i=0; i < handler -> l_read -> size(); i++){ // stopping all children
00105 
00106     incoming = dynamic_cast<IncomingSocket*>(handler -> l_read -> get(i));
00107 
00108     if(incoming -> GetParent() == this){
00109 
00110       incoming -> Close();
00111       handler -> Remove(incoming);
00112       i--;
00113 
00114       }
00115 
00116     }
00117 
00118   Close();
00119   handler -> Remove(this);
00120   memset(&saddr, 0, sizeof(saddr));
00121   running = false;
00122   port = -1;
00123   addr = "";
00124 
00125   }
00126 
00127 
00128 void ListenServer::OnAccept(){
00129 
00130 // incomplete UDP support
00131   if(type == TYPE_UDP){
00132 
00133     sockaddr_in sa;
00134     socklen_t sa_len;
00135     char buffer[65536];
00136     int ret = recvfrom(GetSock(),buffer,65536,0,(sockaddr*)&sa,&sa_len);
00137 
00138     out((string)"UDP SOCKET FROM " + inet_ntoa(sa.sin_addr) + ":" + itos(htons(sa.sin_port)) + " -> " + buffer);
00139 
00140     return;  
00141     }
00142 
00143   __OnAccept();
00144 
00145   }
00146   
00147 int ListenServer::Accept(sockaddr_in &_saddr){
00148 
00149   if(!running) throw SocketException(NOT_RUNNING);
00150 
00151   socklen_t tmpsize = sizeof(saddr);
00152 #ifdef _WIN32
00153   socket_t ret = accept(GetSock(), (SOCKADDR*) &_saddr, &tmpsize);
00154 #else
00155   socket_t ret = accept(GetSock(), (sockaddr *) &_saddr, &tmpsize);
00156 #endif
00157 
00158   if(ret == -1) throw SocketException(ACCEPT_FAILED);
00159 
00160   return ret;
00161 
00162   }
00163 
00164 void ListenServer::OnAcceptFailed(){
00165 
00166 //   if(!running) throw SocketException(NOT_RUNNING); ???
00167   
00168   __OnAcceptFailed();
00169 
00170   }
00171 
00172 void ListenServer::__OnAccept(){
00173 
00174   struct sockaddr_in _saddr;
00175   int ret = Accept(_saddr); // accept any connection
00176 
00177   IncomingSocket* IS = new IncomingSocket(ret, _saddr, this);
00178 
00179   SocketHandler* handler = SocketHandler::getInstance();
00180   if(!handler) throw SocketException(SOCKETHANDLING_FAILED);
00181   handler -> Add(IS);
00182 
00183   }
00184 
00185 
00186 // Bind to a port
00187 void ListenServer::Bind(string host, int port){ // SocketType needs to be implemented
00188 
00189   addr = host;
00190   memset(&saddr, 0, sizeof(saddr));
00191   saddr.sin_family = AF_INET;
00192   saddr.sin_port = htons(port);
00193 
00194   if(host == ""){
00195   
00196     saddr.sin_addr.s_addr = INADDR_ANY;
00197   
00198     }else{
00199         
00200 //  static char myhostname[MAXHOSTNAMELEN+1];
00201 //  gethostname(myhostname, MAXHOSTNAMELEN);
00202 
00203     saddr.sin_addr.s_addr = inet_addr(host.c_str());
00204 
00205         }
00206 
00207   Bind();
00208 
00209   }
00210 
00211 // Do the binding
00212 void ListenServer::Bind(){
00213 
00214   MakeSock();
00215 
00216   if(setsockopt(GetSock(), SOL_SOCKET, SO_REUSEADDR, "1", sizeof(int)) == -1)
00217     throw SocketException(BIND_FAILED);
00218 
00219   int ret = bind(GetSock(), (sockaddr*) &saddr, sizeof(saddr));
00220 
00221   if(ret < 0) throw SocketException(BIND_FAILED);
00222 
00223 //  WSACleanup(); -> when?
00224 
00225   }
00226 
00227 // Listen on a port
00228 void ListenServer::Listen(int opt){
00229 
00230   if(GetSock() == -1) throw SocketException(BIND_FIRST);
00231 
00232   int conn = listen(GetSock(), opt);
00233 
00234   if(conn == -1) throw SocketException(LISTEN_FAILED);
00235 
00236   }

SourceForge.netLogo