Logo
~Apps~
~Projects~
~Contact~


PeerHandler.cpp

Go to the documentation of this file.
00001 
00006 /*
00007 Copyright (C) 2005  Anders Hedstrom
00008 
00009 This program is free software; you can redistribute it and/or
00010 modify it under the terms of the GNU General Public License
00011 as published by the Free Software Foundation; either version 2
00012 of the License, or (at your option) any later version.
00013 
00014 This program is distributed in the hope that it will be useful,
00015 but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 GNU General Public License for more details.
00018 
00019 You should have received a copy of the GNU General Public License
00020 along with this program; if not, write to the Free Software
00021 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 */
00023 #ifdef _WIN32
00024 #pragma warning(disable:4786)
00025 #include <direct.h>
00026 #endif
00027 #include <sys/stat.h>
00028 #include <sys/types.h>
00029 #include <stdarg.h>
00030 
00031 #include "Session.h"
00032 #include "tSocket.h"
00033 #include "cstring.h"
00034 #include "pSocket.h"
00035 #include "Peer.h"
00036 #include "StatusSocket.h"
00037 #include "PeerHandler.h"
00038 
00039 #ifdef _DEBUG
00040 #define DEB(x) x
00041 #else
00042 #define DEB(x)
00043 #endif
00044 
00045 
00046 
00047 PeerHandler::PeerHandler()
00048 :SocketHandler()
00049 ,m_listen_port(0)
00050 ,m_choke_timer(300)
00051 ,m_min_peers(10)
00052 ,m_max_peers(20)
00053 ,m_local_choke_time(30)
00054 ,m_ignore_choke(false)
00055 ,m_max_request_age(30)
00056 ,m_quit(false)
00057 ,m_debug(0)
00058 ,m_downloaders(4)
00059 ,m_optimistic(1)
00060 {
00061         srand(time(NULL) * (time_t)this);
00062 }
00063 
00064 
00065 PeerHandler::PeerHandler(StdLog *p)
00066 :SocketHandler(p)
00067 ,m_listen_port(0)
00068 ,m_choke_timer(300)
00069 ,m_min_peers(10)
00070 ,m_max_peers(20)
00071 ,m_local_choke_time(30)
00072 ,m_ignore_choke(false)
00073 ,m_max_request_age(30)
00074 ,m_quit(false)
00075 ,m_debug(0)
00076 ,m_downloaders(4)
00077 ,m_optimistic(1)
00078 {
00079 }
00080 
00081 
00082 PeerHandler::~PeerHandler()
00083 {
00084         while (m_sessions.size())
00085         {
00086                 session_m::iterator it = m_sessions.begin();
00087                 Session *p = (*it).second;
00088                 delete p;
00089                 m_sessions.erase(it);
00090         }
00091 }
00092 
00093 
00094 void PeerHandler::RegSession(Session *p)
00095 {
00096         m_sessions[p -> GetInfoHash()] = p;
00097 }
00098 
00099 
00100 bool PeerHandler::SessionExists(const std::string& hash)
00101 {
00102         for (session_m::iterator it = m_sessions.begin(); it != m_sessions.end(); it++)
00103         {
00104                 if ((*it).first == hash && dynamic_cast<Session *>((*it).second))
00105                         return true;
00106         }
00107         return false;
00108 }
00109 
00110 
00111 void PeerHandler::mkpath(const std::string& path)
00112 {
00113         for (size_t i = 0; i < path.size(); i++)
00114         {
00115                 if (path[i] == '/')
00116                 {
00117 #ifdef _WIN32
00118                         _mkdir(path.substr(0, i).c_str());
00119 #else
00120                         mkdir(path.substr(0, i).c_str(), 0750);
00121 #endif
00122                 }
00123         }
00124 }
00125 
00126 
00127 Session *PeerHandler::GetSession(const std::string& hash)
00128 {
00129         for (session_m::iterator it = m_sessions.begin(); it != m_sessions.end(); it++)
00130         {
00131                 if ((*it).first == hash && dynamic_cast<Session *>((*it).second))
00132                         return (*it).second;
00133         }
00134         return NULL;
00135 }
00136 
00137 
00138 void PeerHandler::Tick(time_t now)
00139 {
00140         for (session_m::iterator it = m_sessions.begin(); it != m_sessions.end(); it++)
00141         {
00142                 Session *sess = (*it).second;
00143                 if (sess)
00144                 {
00145                         if (now > sess -> GetTimeTracker() + sess -> GetInterval())
00146                         {
00147                                 tSocket *p = new tSocket(*this, sess -> GetInfoHash());
00148                                 p -> SetDeleteByHandler();
00149                                 Add(p);
00150                                 sess -> SetTimeTracker();
00151                         }
00152                         sess -> Update();
00153                 }
00154         }
00155 }
00156 
00157 
00158 void PeerHandler::dprintf(int id, char *format, ...)
00159 {
00160 //      char *colors = "rgybmcwlRGYBMCWL";
00161         char *colors = "rgymcRGYBMCWL";
00162         va_list ap;
00163         va_start(ap, format);
00164         char tmp[5000];
00165 #ifdef _WIN32
00166         vsprintf(tmp, format, ap);
00167         va_end(ap);
00168         printf("%s\n", tmp);
00169 #else
00170         vsnprintf(tmp, 5000, format, ap);
00171         va_end(ap);
00172         cstring str;
00173         char slask[10];
00174         sprintf(slask, "&%c", colors[id % strlen(colors)]);
00175         str = slask;
00176         str += tmp;
00177         str += "&n";
00178         printf("%s\n", str.c_str());
00179         if (0)
00180         {
00181                 FILE *fil = fopen("btlog","at");
00182                 if (!fil)
00183                         fil = fopen("btlog","wt");
00184                 fprintf(fil,"%s\n", str.c_str());
00185                 fclose(fil);
00186         }
00187 #endif
00188 }
00189 
00190 
00191 size_t PeerHandler::PeerCount(const std::string& hash)
00192 {
00193         size_t q = 0;
00194         for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00195         {
00196                 pSocket *p = dynamic_cast<pSocket *>((*it).second);
00197                 if (p && p -> GetHash() == hash)
00198                 {
00199                         q++;
00200                 }
00201         }
00202         return q;
00203 }
00204 
00205 
00206 bool PeerHandler::Connected(Peer *peer)
00207 {
00208         for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00209         {
00210                 pSocket *p = dynamic_cast<pSocket *>((*it).second);
00211                 if (p && p -> GetHash() == peer -> GetHash() && p -> GetRemoteAddress() == peer -> GetIP())
00212                 {
00213                         return true;
00214                 }
00215         }
00216         return false;
00217 }
00218 
00219 
00220 pSocket *PeerHandler::PeerSocket(Peer *peer)
00221 {
00222         for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00223         {
00224                 pSocket *p = dynamic_cast<pSocket *>((*it).second);
00225                 if (p && p -> GetHash() == peer -> GetHash() && p -> GetRemoteAddress() == peer -> GetIP())
00226                 {
00227                         return p;
00228                 }
00229         }
00230         return NULL;
00231 }
00232 
00233 
00234 void PeerHandler::SendHave(const std::string& hash,size_t piece)
00235 {
00236         for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00237         {
00238                 pSocket *p = dynamic_cast<pSocket *>((*it).second);
00239                 if (p && p -> GetHash() == hash && p -> CTS() )
00240                 {
00241                         p -> SendHave(piece);
00242                 }
00243         }
00244 }
00245 
00246 
00247 void PeerHandler::Save()
00248 {
00249         for (session_m::iterator it = m_sessions.begin(); it != m_sessions.end(); it++)
00250         {
00251                 Session *sess = (*it).second;
00252                 sess -> Save();
00253         }
00254 }
00255 
00256 
00257 void PeerHandler::Show(StatusSocket *sock)
00258 {
00259         for (session_m::iterator it = m_sessions.begin(); it != m_sessions.end(); it++)
00260         {
00261                 Session *sess = (*it).second;
00262                 sess -> Status(sock);
00263         }
00264 }
00265 
00266 
00267 void PeerHandler::CheckDownloadRate()
00268 {
00269         // TODO: disabled
00270         return;
00271 
00272         std::map<pSocket *,size_t> mmap;
00273         size_t max = 0;
00274 DEB(printf("CheckDownloadRate()\n");)
00275         for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00276         {
00277                 pSocket *p = dynamic_cast<pSocket *>((*it).second);
00278                 if (p)
00279                 {
00280                         Peer *peer = p -> GetPeer();
00281                         if (p && peer && p -> CTS() && !peer -> IsChoked())
00282                         {
00283                                 size_t sz;
00284                                 if (p -> GetDownloadRate(sz))
00285                                 {
00286                                         mmap[p] = sz;
00287                                         max = MAX(max,sz);
00288                                 }
00289                         }
00290                 }
00291         }
00292         if (mmap.size() == GetDownloaders() + GetOptimistic() )
00293         {
00294                 pSocket *least = NULL;
00295                 for (std::map<pSocket *,size_t>::iterator it = mmap.begin(); it != mmap.end(); it++)
00296                 {
00297                         pSocket *sock = (*it).first;
00298                         size_t sz = (*it).second;
00299                         if (sz < max)
00300                         {
00301                                 least = sock;
00302                                 max = sz;
00303                         }
00304                 }
00305                 if (least)
00306                 {
00307 //DEB(printf("Kicking pSocket with download rate %d bytes/sec\n", max);)
00308                         least -> SendChoke(true);
00309                 }
00310         }
00311 }
00312 
00313 
00314 std::string PeerHandler::GetTime()
00315 {
00316         char slask[100];
00317 #ifdef _WIN32
00318         SYSTEMTIME time;
00319         ::GetLocalTime(&time);
00320         sprintf(slask, "%ld.%03ld", time.wHour * 3600 + 
00321                 time.wMinute + 60 + time.wSecond, time.wMilliseconds);
00322 #else
00323         struct timeval tv;
00324         struct timezone tz;
00325         gettimeofday(&tv, &tz);
00326         sprintf(slask, "%ld.%06ld", tv.tv_sec, tv.tv_usec);
00327 #endif
00328         return slask;
00329 }
00330 
00331 
Page, code, and content Copyright (C) 2006 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4