poolsock

本文介绍了一个客户端连接池的设计实现,通过预建立socket连接以提升高并发情况下的访问效率。该连接池支持TCP和UDP连接,并提供了初始化、释放、关闭等功能。

=-------------------------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;
}

【无人机】基于改进粒子群算法的无人机路径规划研究[和遗传算法、粒子群算法进行比较](Matlab代码实现)内容概要:本文围绕基于改进粒子群算法的无人机路径规划展开研究,重点探讨了在复杂环境中利用改进粒子群算法(PSO)实现无人机三维路径规划的方法,并将其与遗传算法(GA)、标准粒子群算法等传统优化算法进行对比分析。研究内容涵盖路径规划的多目标优化、避障策略、航路点约束以及算法收敛性和寻优能力的评估,所有实验均通过Matlab代码实现,提供了完整的仿真验证流程。文章还提到了多种智能优化算法在无人机路径规划中的应用比较,突出了改进PSO在收敛速度和全局寻优方面的优势。; 适合人群:具备一定Matlab编程基础和优化算法知识的研究生、科研人员及从事无人机路径规划、智能优化算法研究的相关技术人员。; 使用场景及目标:①用于无人机在复杂地形或动态环境下的三维路径规划仿真研究;②比较不同智能优化算法(如PSO、GA、蚁群算法、RRT等)在路径规划中的性能差异;③为多目标优化问题提供算法选型和改进思路。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注算法的参数设置、适应度函数设计及路径约束处理方式,同时可参考文中提到的多种算法对比思路,拓展到其他智能优化算法的研究与改进中。
标题中的"EthernetIP-master.zip"压缩文档涉及工业自动化领域的以太网通信协议EtherNet/IP。该协议由罗克韦尔自动化公司基于TCP/IP技术架构开发,已广泛应用于ControlLogix系列控制设备。该压缩包内可能封装了协议实现代码、技术文档或测试工具等核心组件。 根据描述信息判断,该资源主要用于验证EtherNet/IP通信功能,可能包含测试用例、参数配置模板及故障诊断方案。标签系统通过多种拼写形式强化了协议主题标识,其中"swimo6q"字段需结合具体应用场景才能准确定义其技术含义。 从文件结构分析,该压缩包采用主分支命名规范,符合开源项目管理的基本特征。解压后预期可获取以下技术资料: 1. 项目说明文档:阐述开发目标、环境配置要求及授权条款 2. 核心算法源码:采用工业级编程语言实现的通信协议栈 3. 参数配置文件:预设网络地址、通信端口等连接参数 4. 自动化测试套件:包含协议一致性验证和性能基准测试 5. 技术参考手册:详细说明API接口规范与集成方法 6. 应用示范程序:展示设备数据交换的标准流程 7. 工程构建脚本:支持跨平台编译和部署流程 8. 法律声明文件:明确知识产权归属及使用限制 该测试平台可用于构建协议仿真环境,验证工业控制器与现场设备间的数据交互可靠性。在正式部署前开展此类测试,能够有效识别系统兼容性问题,提升工程实施质量。建议用户在解压文件后优先查阅许可协议,严格遵循技术文档的操作指引,同时需具备EtherNet/IP协议栈的基础知识以深入理解通信机制。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
本项目基于STM32单片机,设计并实现了一个温湿度及可燃气体浓度检测系统。该系统能够实时采集环境中的温度、湿度和可燃气体浓度,并通过OLED显示屏显示相关数据。系统还具备自动控制功能,当检测到环境参数超出设定阈值时,能够自动启动相应的电机进行散热、加湿或排气,以维持环境的安全和舒适。 主要功能 数据采集与显示: 使用DHT11传感器采集环境温度和湿度。 使用MQ4传感器采集可燃气体浓度。 通过OLED显示屏实时显示采集到的温湿度、可燃气体浓度以及设定的阈值。 自动控制: 当检测到温度超过设定值时,自动启动散热电机。 当检测到湿度低于设定值时,自动启动加湿电机。 当检测到可燃气体浓度超过设定值时,自动启动排气电机。 参数设置: 通过按键设置温度上限、湿度下限和可燃气体浓度上限。 硬件组成 STM32单片机 OLED显示屏 DHT11温湿度传感器 MQ4可燃气体传感器 散热电机、加湿电机、排气电机 按键模块 软件设计 本项目采用C语言编程,使用Keil5进行代码编写。程序代码中包含详细的中文注释,便于新手理解和学习。仿真部分使用Proteus软件进行,仿真演示视频使用的是Proteus8.9版本。 使用说明 下载与解压: 下载资源文件后,请先解压(建议解压到桌面上,文件路径太深会导致程序打开异常)。 程序打开: 解压后使用Keil5打开主程序文件。 仿真文件: 使用Proteus软件打开仿真文件进行仿真测试。 资料清单 主程序代码 仿真文件 相关软件包(如Keil5、Proteus等)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值