Peercast核心代码执行流程

执行的流程大致如下:
Peercast启动时创建servMgr对象
servMgr启动两个服务器线程,分别为servProc和idleProc
servProc启动两个监听servent,分别用于监听7144和7145端口
监听servent启动服务器监听线程Servent::servProc
当服务器监听线程监测到有新连接进入时,给这个连接分配新的servent
新的servent初始化连接信息,并启动incomingProc线程
incomingProc线程调用handshakeIncoming进行处理
handshakeIncoming读取发送进来的请求,若为HTTP请求,则调用handshakeHTTP进行处理
handshakeHTTP处理HTTP请求,并做出相应的回复.其中若是频道请求则调用handshakePLS进行处理,若是控制请求(ADMIN请求)则调用handshakeCmd进行处理,如果是播放请求则调用triggerChannel进行相应处理(此部分详见播放模块分析)


WINDOWS程序都是从WinMain开始执行
int APIENTRY WinMain()
{
 peercastInst = new MyPeercastInst();
 peercastApp = new MyPeercastApp();

 peercastInst->init();
}

// 整个程序的初始化,创建sys、servMgr和chanMgr对象以及从配置文件中读取信息
// sys、servMgr和chanMgr作为系统中三个最重要的全局变量,支撑起了Peercast核心代码的大部分操作
// 其中sys用来提供底层操作,如创建SOCKET和获取系统时间等,可理解为一个实现系统库的类的对象
// servMgr用来管理网络传输,实现监听、发送、接收信息等功能,chanMgr用来实现对频道的管理
void APICALL PeercastInstance::init()
{
 sys = createSys();
 servMgr = new ServMgr();
 chanMgr = new ChanMgr();

 //读取配置文件中配置信息
 if (peercastApp->getIniFilename())
  servMgr->loadSettings(peercastApp->getIniFilename());

 servMgr->start();
}

// servMgr启动两个线程,其中serverProc(服务器线程)监听7144端口,处理进来的连接和发送数据
// idleProc在程序的空闲时间进行操作,如向YP发送信息等
bool ServMgr::start()
{
 serverThread.func = ServMgr::serverProc;
 if (!sys->startThread(&serverThread))
  return false;

 idleThread.func = ServMgr::idleProc;
 if (!sys->startThread(&idleThread))
  return false;

 return true;
}

//下面我们看看服务器线程的执行情况
// --------------------------------------------------
// 启动服务器进程,分配两个servent,并初始化sock,默认serv监听7144端口,serv2监听7145端口
int ServMgr::serverProc(ThreadInfo *thread)
{
 Servent *serv = servMgr->allocServent();
 Servent *serv2 = servMgr->allocServent();

 while (thread->active)
 {
  if (servMgr->autoServe)
  {
   if ((!serv->sock) || (!serv2->sock))
   {
    LOG_DEBUG("Starting servers");
    {
     Host h = servMgr->serverHost;

     if (!serv->sock)
      serv->initServer(h);

     h.port++;
     if (!serv2->sock)
      serv2->initServer(h);
    }
   }
  }else{
   // stop server
   serv->abort();  // force close
   serv2->abort();  // force close

   // cancel incoming connectuions
   Servent *s = servMgr->servents;
   while (s)
   {
    if (s->type == Servent::T_INCOMING)
     s->thread.active = false;
    s=s->next;
   }

   servMgr->setFirewall(ServMgr::FW_ON);
  }
   
  sys->sleepIdle();

 }

 sys->endThread(thread);

 return 0;
}

//每个监听的servent启动一个监听线程
// 启动serverProc线程进行服务器监听
bool Servent::initServer(Host &h)
{
 createSocket();
 sock->bind(h);
 thread.data = this;
 thread.func = serverProc;
 type = T_SERVER;
 if (!sys->startThread(&thread))
  throw StreamException("Can`t start thread");

 return true;
}

//下面我们看看服务器监听线程是如何运行的
int Servent::serverProc(ThreadInfo *thread)
{
 Servent *sv = (Servent*)thread->data;

 try
 {
  if (!sv->sock)
   throw StreamException("Server has no socket");

  sv->setStatus(S_LISTENING);   //设置为监听状态


  char servIP[64];
  sv->sock->host.toStr(servIP);  //servIP为"127.0.0.1:7144"

  while ((thread->active) && (sv->sock->active()))
  {
   if (servMgr->numActiveOnPort(sv->sock->host.port) < servMgr->maxServIn)
   {
    ClientSocket *cs = sv->sock->accept(); //创建一个新的socket以接受连接
    //循环判断cs的值,若cs不为空,则表示有新的连接进入
    //这是非阻塞方式判断是否有新连接的一种方法
    if (cs)
    { 
     LOG_DEBUG("accepted incoming");
     Servent *ns = servMgr->allocServent(); //创建servent ns来处理连接请求
     if (ns)
     {
      servMgr->lastIncoming = sys->getTime();
      ns->servPort = sv->sock->host.port;
      ns->networkID = servMgr->networkID;
      ns->initIncoming(cs,sv->allow);     //使用initIncoming处理发送过来的信息
     }else
      LOG_ERROR("Out of servents");
    }
   }
   sys->sleep(100);
  }
 }catch(StreamException &e)
 {
  LOG_ERROR("Server Error: %s:%d",e.msg,e.err);
 }

 
 LOG_DEBUG("Server stopped");

 sv->kill();
 sys->endThread(thread);
 return 0;
}

// 当监听服务器线程检测到有新连接进入时,分配新的servent,并初始化Incoming,启动线程调用incomingProc进行incoming的处理
void Servent::initIncoming(ClientSocket *s, unsigned int a)
{

 try{

  checkFree();

  type = T_INCOMING;
  sock = s;
  allow = a;
  thread.data = this;
  thread.func = incomingProc;

  setStatus(S_PROTOCOL);

  char ipStr[64];
  sock->host.toStr(ipStr);
  LOG_DEBUG("Incoming from %s",ipStr);


  if (!sys->startThread(&thread))
   throw StreamException("Can`t start thread");
 }catch(StreamException &e)
 {
  //LOG_ERROR("!!FATAL!! Incoming error: %s",e.msg);
  //servMgr->shutdownTimer = 1;   
  kill();

  LOG_ERROR("INCOMING FAILED: %s",e.msg);

 }
}

// 调用handshakeIncoming进行Incoming的处理
int Servent::incomingProc(ThreadInfo *thread)
{
// thread->lock();

 Servent *sv = (Servent*)thread->data;
 
 char ipStr[64];
 sv->sock->host.toStr(ipStr);

 try
 {
  sv->handshakeIncoming();
 }catch(HTTPException &e)
 {
  try
  {
   sv->sock->writeLine(e.msg);
   if (e.code == 401)
    sv->sock->writeLine("WWW-Authenticate: Basic realm=/"PeerCast/"");
   sv->sock->writeLine("");
  }catch(StreamException &){}
  LOG_ERROR("Incoming from %s: %s",ipStr,e.msg);
 }catch(StreamException &e)
 {
  LOG_ERROR("Incoming from %s: %s",ipStr,e.msg);
 }


 sv->kill();
 sys->endThread(thread);
 return 0;
}

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值