poolsock

=-------------------------socketpool.h

 

#pragma once
#include "Const.h"
#include <list>
#include "dll.h"


//
// 客户端连接池
// 在客户端连接前,先建立socket,在连接时,可以加快响应速度。
// 在高并发的情况下,可以提高访问量
//

class IOCP_API CClientSocketPool
{
public:
 CClientSocketPool(void);
 virtual ~CClientSocketPool(void);

public:

 //初始化连接池
 int Initialize(int count, SOCKET listenSock, HANDLE hCompletePort);

 //增加TCP监听缓冲区
 int AddTCPAcceptBuff( int count);

 //初始UDP连接池
 int InitUDPSocket(SOCKET listenSock, HANDLE hCompletePort, int count = 1);


 //关闭连接池
 int Close(void);


 //释放连接
 int ReleaseClientSock(ClientSocket* pClientSock);

 int GetTcpClientSock(std::list<ClientSocket*>& clientSocketList)
 {
  clientSocketList.clear();
  EnterCriticalSection(&cs);
  clientSocketList = m_clientSocketList;
  LeaveCriticalSection(&cs);
  return 0;
 }
private:

 //设置socket参数
 int SettingClientSocket(ClientSocket* pClientSocket);

private:
 int m_iSocketCount;
 SOCKET m_listenSock;
 HANDLE hCompletePort;
 LPFN_ACCEPTEX m_lpfnAcceptEx;

 CRITICAL_SECTION cs;

 std::list<ClientSocket*> m_clientSocketList;  //tcp连接池
 std::list<ClientSocket*> m_UDPSocketList;    //udp连接池
};

 

---------------------socketpool.cpp

#include "SocketPool.h"

CClientSocketPool::CClientSocketPool(void)
{
 InitializeCriticalSection(&cs);
 m_lpfnAcceptEx = NULL;//2008-9-9 modify by meng junshen
}

CClientSocketPool::~CClientSocketPool(void)
{
 //释放所有创建的ClientSock
 Close();

 DeleteCriticalSection(&cs);
}

int CClientSocketPool::Initialize( int count, SOCKET listenSock, HANDLE hCompletePort )
{
 this->m_listenSock = listenSock;
 this->hCompletePort = hCompletePort;

 //获取AcceptEx函数指针
 GUID wsaidAcceptEx = WSAID_ACCEPTEX;    
 DWORD dwBytes = 0;

 WSAIoctl(listenSock,
   SIO_GET_EXTENSION_FUNCTION_POINTER,
   &wsaidAcceptEx,
   sizeof(wsaidAcceptEx),
   &m_lpfnAcceptEx,
   sizeof(m_lpfnAcceptEx),
   &dwBytes,
   NULL,
   NULL);

 //创建指定数量的Socket
 for(int i=0; i < count; i++)
 {
  ClientSocket* pClientSock = new ClientSocket();
  pClientSock->bIsServer = true;
  pClientSock->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  
  SettingClientSocket(pClientSock);

  m_clientSocketList.push_back(pClientSock);
 }
 return 0;
}


//释放所有创建的ClientSock
int CClientSocketPool::Close(void)
{
 ClientSocket* pClientSock = NULL;

 EnterCriticalSection(&cs);

 //关闭所有的连接
    std::list<ClientSocket*>::iterator itr = m_clientSocketList.begin();
 for (; itr != m_clientSocketList.end(); ++itr)
 {
  pClientSock = *itr;
  
  LINGER linger;
  linger.l_onoff = 1;
  linger.l_linger = 0;
  setsockopt( pClientSock->socket, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof(linger) );
  CancelIo((HANDLE)  pClientSock->socket);
  closesocket(pClientSock->socket);

  Sleep(1);
  delete pClientSock;

  pClientSock = NULL;
 }

 //析放所有udp连接资源
 itr = m_UDPSocketList.begin();
 for (; itr != m_UDPSocketList.end(); ++itr)
 {   if (*itr)  //关闭socket
  {
   closesocket((*itr)->socket);
  }
  delete *itr;
  *itr = NULL;
 }
 m_UDPSocketList.clear();
 m_clientSocketList.clear();
   
 LeaveCriticalSection(&cs); 

 return 0;
}


//释放ClientSocket,将重新创建一个Socket加入到等待列表
int CClientSocketPool::ReleaseClientSock( ClientSocket* pClientSock )
{
 if( pClientSock )
 {
  LINGER linger;
  linger.l_onoff = 1;
  linger.l_linger = 0;
  setsockopt( pClientSock->socket, SOL_SOCKET, SO_LINGER, (char *)&linger, sizeof(linger) );
  CancelIo((HANDLE)  pClientSock->socket);
  shutdown(pClientSock->socket, 1000);
  //closesocket(pClientSock->socket);

  //pClientSock->bIsServer = FALSE;//2008-9-9 modify by meng junshen
 
  pClientSock->socket = INVALID_SOCKET;
  if (pClientSock->bIsServer)
  {
   //重新创建一个Socket来等待
   pClientSock->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
   SettingClientSocket(pClientSock); 
  }
   
 }

 return 0;
}

//设置Socket参数,异步等待Socket连接,并关联完成端口
int CClientSocketPool::SettingClientSocket( ClientSocket* pClientSock )
{

 if ( pClientSock )
 {
  SOCKET socket = pClientSock->socket;

  //异步等待Socket连接
  memset( &(pClientSock->olex) , 0, sizeof(OVERLAPPEDEX));

  pClientSock->bIsUPDSock = FALSE;   //设置UDP连接标志
  pClientSock->olex.pClientSock = pClientSock;
  pClientSock->olex.ioType = ACCEPT;
  pClientSock->olex.wsabuf.buf = pClientSock->olex.buf;
  pClientSock->bytesTransferred = 0;

  if (m_lpfnAcceptEx != NULL)//2008-9-9 modify by meng junshen
  {
   DWORD ret = m_lpfnAcceptEx(m_listenSock,
    socket,
    pClientSock->AddressBuffer,
    0,
    SOCKADDR_IN_SIZE,
    SOCKADDR_IN_SIZE,
    &(pClientSock->bytesTransferred),
    (LPOVERLAPPED)&(pClientSock->olex));
   
   
   //关联完成端口
   CreateIoCompletionPort((HANDLE)socket,hCompletePort,(DWORD)pClientSock,0);
  }
 }

 return 0;
}


/***********************************************************************************************************/
//Function: InitUDPSocket
//Notes: 初始化完成端口UDP连接,投递udp数据接受
//
//Input: ClientSocket* listenSock用户的连接信息
//       HANDLE hCompletePort完成端口句柄
//       count 读取数据投递数量


/***********************************************************************************************************/
int CClientSocketPool::InitUDPSocket( SOCKET listenSock, HANDLE hCompletePort, int count)
{
 int res = 0;
 ClientSocket* pClientSock = new ClientSocket();
 if ( pClientSock )
 {
  pClientSock->socket = listenSock;
  SOCKET socket = pClientSock->socket;

  //关联完成端口
  CreateIoCompletionPort((HANDLE)listenSock, hCompletePort,(DWORD)pClientSock, 0);
  m_UDPSocketList.push_back(pClientSock);

  //准备接受数据包
  for (int i =0; i < 4; ++i)
  {
   if (NULL == pClientSock)
   {
    pClientSock = new ClientSocket();
                pClientSock->socket = listenSock;
    m_UDPSocketList.push_back(pClientSock);
   }
   
   //异步等待Socket连接
   memset( &(pClientSock->olex) , 0, sizeof(OVERLAPPEDEX));
   pClientSock->olex.pClientSock = pClientSock;
   pClientSock->olex.wsabuf.buf = pClientSock->olex.buf;
   pClientSock->bytesTransferred = 0;
   pClientSock->bIsUPDSock = TRUE;   //设置UDP连接标志
   pClientSock->iAddrLen = sizeof(sockaddr_in);

   DWORD flag = MSG_PARTIAL;
   DWORD ioSize = 0;
   pClientSock->olex.ioType = READ;
   pClientSock->olex.wsabuf.len = DATA_BUF_LENGHT;

   int rtSend = WSARecvFrom(
    pClientSock->socket,
    &pClientSock->olex.wsabuf,
    1,
    &pClientSock->bytesTransferred,
    &flag,
    (sockaddr*)pClientSock->AddressBuffer,
    &pClientSock->iAddrLen,
    (LPOVERLAPPED)&pClientSock->olex,
    0);
   res = GetLastError();
   if ( SOCKET_ERROR == rtSend &&
    WSA_IO_PENDING != GetLastError())
   {
    closesocket(listenSock);   
   }
   pClientSock = NULL;
  }
 }
 return 0;
}
/***********************************************************************************************************/
//Function: AddTCPAcceptBuff
//Notes: 增加TCP监听缓冲区
//
//Input: count需要添加的接收连接缓冲区数量

/***********************************************************************************************************/
int CClientSocketPool::AddTCPAcceptBuff(int count)
{
 //获取AcceptEx函数指针
 if (NULL == m_lpfnAcceptEx)
 {
  GUID wsaidAcceptEx = WSAID_ACCEPTEX;    
  DWORD dwBytes = 0;

  WSAIoctl(m_listenSock,
   SIO_GET_EXTENSION_FUNCTION_POINTER,
   &wsaidAcceptEx,
   sizeof(wsaidAcceptEx),
   &m_lpfnAcceptEx,
   sizeof(m_lpfnAcceptEx),
   &dwBytes,
   NULL,
   NULL);
 }
 //创建指定数量的Socket
 for(int i=0; i < count; i++)
 {
  ClientSocket* pClientSock = new ClientSocket();
  pClientSock->socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  SettingClientSocket(pClientSock);

  m_clientSocketList.push_back(pClientSock);
 }
 return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值