面向连接的Socket Server的简单实现

2013-11-14 17:05  18人阅读  评论(0)  收藏  举报

目录(?)[-]

  1. 一基本原理
  2. 二对Socket的封装
  3. 三线程池的实现
  4. 四连接池的实现
  5. 五监听线程的实现

一、基本原理

有时候我们需要实现一个公共的模块,需要对多个其他的模块提供服务,最常用的方式就是实现一个Socket Server,接受客户的请求,并返回给客户结果。

这经常涉及到如果管理多个连接及如何多线程的提供服务的问题,常用的方式就是连接池和线程池,基本流程如下:

首先服务器端有一个监听线程,不断监听来自客户端的连接。

当一个客户端连接到监听线程后,便建立了一个新的连接。

监听线程将新建立的连接放入连接池进行管理,然后继续监听新来的连接。

线程池中有多个服务线程,每个线程都监听一个任务队列,一个建立的连接对应一个服务任务,当服务线程发现有新的任务的时候,便用此连接向客户端提供服务。

一个Socket Server所能够提供的连接数可配置,如果超过配置的个数则拒绝新的连接。

当服务线程完成服务的时候,客户端关闭连接,服务线程关闭连接,空闲并等待处理新的任务。

连接池的监控线程清除其中关闭的连接对象,从而可以建立新的连接。

二、对Socket的封装

Socket的调用主要包含以下的步骤:

调用比较复杂,我们首先区分两类Socket,一类是Listening Socket,一类是Connected Socket.

Listening Socket由MySocketServer负责,一旦accept,则生成一个Connected Socket,又MySocket负责。

MySocket主要实现的方法如下:

int MySocket::write(const>         int left = length;
       >         while(left > 0)
        {
               >                 if(ret == 0)
                       >                 {
                       >                 index += ret;
        }
        if(left > 0)
                return -1;
        return 0;
}

int MySocket::read(char *>         int left = length;
       >         while(left > 0)
        {
               >                 if(ret == 0)
                       >                         return -1;
               >                 index += ret;
        }

        return index;
}

int MySocket::status()
{
       >         timeout.tv_usec = 0;

       >         if(status < 0)
               >         else if(status == 0)
               >         else
               >         return ret;
}

int MySocket::close()
{
       >         lin.l_linger = 0;
       >

int MySocketServer::init(int>         {
               >         serverAddr.sin_family = AF_INET;
       >

       >         {
                ::close(m_socket);
               >         {
                ::close(m_socket);
                return -1;
        }

       >         lin.l_linger = 0;

       >         m_inited = true;
        return 0;
}

MySocket * MySocketServer::accept()
{
       >         if((sock = ::accept(m_socket, (struct sockaddr *)&clientAddr, &clientAddrSize)) == -1)
        {
               >         return socket;
}

MySocket * MySocketServer::accept(int>         timeout.tv_usec = 0;

       >         if(status < 0)
               >                 return NULL;

        if(FD_ISSET(m_socket, &checkset))
        {
                return accept();
        }
}

三、线程池的实现

一个线程池一般有一个任务队列,启动的各个线程从任务队列中竞争任务,得到的线程则进行处理:list<MyTask *> >

void * __thread_new_proc(void *p)
{
    ((MyThread *)p)->run();
   >

int MyThread::start()
{

   >     pthread_attr_destroy(&attr);

   >         return –1;

}

int MyThread::stop()
{

   >

   >         return –1;
}

int MyThread::join()

{

   >

   >

        return –1;

}

void MyThread::run()

{

   >

    {

        MyTask *pTask =>

        {

           >

int MyThreadPool::init()
{

   >     pthread_condattr_destroy(&cond_attr);

   >         return –1;

   >     pthread_mutexattr_destroy(&attr);

   >         return –1;

   >     {
        MyThread *thread = new MyThread(i+1, this);        
        m_threads.push_back(thread);
    }

    return 0;
}

int MyThreadPool::start()
{
    int ret;
   >     {        
      >        if (ret != 0)
          >

   >         return –1;
    return 0;
}

void MyThreadPool::addTask(MyTask *ptask)
{
   >         return;

    pthread_mutex_lock(&m_queueMutex);

    m_taskQueue.push_back(ptask);       

    if (m_waitingThreadCount > 0)
        pthread_cond_signal(&m_cond);

    pthread_mutex_unlock(&m_queueMutex);
}

MyTask * MyThreadPool::getNextTask()
{
    MyTask *pTask = NULL; 

   >     {  
        ++m_waitingThreadCount;

       >

   >

void MyTask::process()

{

    //用read从客户端读取指令

    //对指令进行处理

    //用write向客户端写入结果

}

 

四、连接池的实现

每个连接池保存一个链表保存已经建立的连接:list<MyConnection *> *>

void MyConnectionPool::addConnection(MyConnection *>

void MyConnectionPool::managePool()
{

   >     {
        MyConnection *conn = *itr;        
       >             list<MyConnection *>::iterator pos = itr++;
            m_connections->erase(pos);                         
        }
        else if (conn->isError())
        {

            //处理错误的连接
            ++itr;
        }
        else
        {
            ++itr;
        }
    }

    pthread_mutex_unlock(&m_connectionMutex);

}

 

五、监听线程的实现

监听线程需要有一个MySocketServer来监听客户端的连接,每当形成一个新的连接,查看是否超过设置的最大连接数,如果超过则关闭连接,如果未超过设置的最大连接数,则形成一个新的MyConnection,将其加入连接池和线程池。

MySocketServer *pServer =>

while (!stopFlag)

{

    MySocket *>

   >

    {

       >

       > 更多0

  • 上一篇:关于短延迟 sleep usleep nanosleep select
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值