发个IOCP的C++例子
IOCP的c++例子IOCP这个东西连续关注了将近3年的时间,这个代码从哪里找到的已经忘了,下面是作者的信息。感谢他提供的代码! /*++ Copyright (c) 2004 模块名: iomodel.cpp 模块描述: Winsock 完成端口类实现文件 作者: PPP elssann@hotmail.com 开发环境: Visual C++ 6.0, Windows 2000.修订记录: 创建于: 2004.1.16 最后修改日期: 2004.1.23 --*/
1)acl_master是一个跨平台c/c++库,提供了网络通信库及服务器编程框架,同时提供更多的实用功能库及示例。
下载地址:Github: https://github.com/acl-dev/acl
2)聚合数据新闻API接口注册
聚合数据的新闻API接口其官网有提供,本人采用的是阿里云市场->API市场->生活服务栏下提供的,
*注册阿里云,有需要的阿里云产品通用代金券的可以点击下面链接进行领取:
https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=pfb80n4a
阿里云提供聚合数据的新闻API的类似描述
阿里为women提供了该新闻接口10000条免费使用次数并一年内有效,我们在聚合数据新闻API接口需要用到APPCode,其API使用方式可以点击“新闻头条”进入查看其使用介绍
3)acl http实现聚合数据新闻信息的抓取
先定义了http抓取的一些参数
struct HttpApiArg
{
int startTime; //开始抓取信息时间(单位小时)
int endTime; //结束抓取信息时间(单位小时)
std::string addr_; // web 服务器地址
std::string path_; // 本地请求的数据文件
int port_;
std::vector<std::string> stypes_; // 请求数据的子数据类型
//std::string charset_; // 本地请求数据文件的字符集
//std::string to_charset_; // 将服务器响应数据转为本地字符集
std::string authorization; // 访问授权
};
目前聚合数据的新闻访问参数
addr_:toutiao-ali.juheapi.com
path_:/toutiao/index
port_:80
stypes_:可从聚合新闻API使用介绍获知,例如"top"
authorization:其格式“APPCODE ***”,***=注册的AppCode
下来展示采用acl http库抓取聚合数据新闻信息的伪代码
#include "acl_cpp/lib_acl.hpp"
void HttpApiAcl::getHttpInfo()
{
bool accept_gzip = false, send_body = false;
//acl::log::stdout_open(true);
acl::string aclurl, acladdr/*,aclContentType*/;
aclurl.format("http://%s%s", myArgHttp.addr_.c_str(), myArgHttp.path_.c_str());
acladdr.format("%s:%d", myArgHttp.addr_.c_str(), myArgHttp.port_);
//aclContentType.format("application/json; charset=%s", myArgHttp.charset_.c_str());
acl::http_request req(acladdr);//请求
acl::http_header& header = req.request_header();//
//
//header.set_method(acl::HTTP_METHOD_POST);
header.set_method(acl::HTTP_METHOD_GET);
//
//header.set_keep_alive(true);
header.set_keep_alive(false);
header.accept_gzip(accept_gzip ? true : false);
//url
header.set_url(aclurl);
//host
if (header.get_host() == NULL)
{
header.set_host(myArgHttp.addr_.c_str());
printf(">>>set host: %s\r\n", myArgHttp.addr_.c_str());
}
else
printf(">>>host: %s\r\n", header.get_host());
//content_type
//header.set_content_type(aclContentType);
//header.set_content_length(1024);
//param
for (unsigned int i = 0; i < myArgHttp.stypes_.size(); i++) {
header.add_param("type", myArgHttp.stypes_.at(i).c_str());
}
//entry
header.add_entry("Authorization", myArgHttp.authorization.c_str());
//cookie
//header.add_cookie("x-cookie-name", "cookie-value");
bool rc = req.request(NULL, 0);//
// 只所以将 build_request 放在 req.request 后面,是因为
// req.request 内部可能会修改请求头中的字段
acl::string hdr;
header.build_request(hdr);
CLogger::createInstance()->Log(eTipMessage, "request header:\r\n%s\r\n", hdr.c_str());
if (rc == false)
{
CLogger::createInstance()->Log(eTipMessage, "send request error\n");
//break;
return;
}
printf("send request ok\r\n");
// 取出 HTTP 响应头的 Content-Type 字段
const char* p = req.header_value("Content-Type");
if (p == NULL || *p == 0)
{
CLogger::createInstance()->Log(eTipMessage, "no Content-Type");
return;
}
// 分析 HTTP 响应头的数据类型
acl::http_ctype content_type;
content_type.parse(p);
// 响应头数据类型的子类型
const char* stype = content_type.get_stype();
bool ret;
if (stype == NULL)
ret = do_plain(req);
else if (stricmp(stype, "json") == 0)//linux->strcasecmp
ret = do_json(req);
else
ret = do_plain(req);
if (ret == true)
CLogger::createInstance()->Log(eTipMessage, "read ok!\r\n");
}
// 处理 text/plain 类型数据
bool HttpApiAcl::do_plain(acl::http_request& req)
{
acl::string body;
if (req.get_body(body/*, to_charset_.c_str()*/) == false)
{
CLogger::createInstance()->Log(eTipMessage, "get http body error");
return false;
}
printf("body:\r\n(%s)\r\n", body.c_str());
return true;
}
// 处理 text/json 类型数据
bool HttpApiAcl::do_json(acl::http_request& req)
{
acl::json body;
if (req.get_body(body/*, to_charset_.c_str()*/) == false)
{
CLogger::createInstance()->Log(eTipMessage, "get http body error");
return false;
}
//add to cache
std::vector<std::string> initdata;
m_MutexNewsData.Lock();
std::swap(initdata, this->newsData);
m_MutexNewsData.Unlock();
curIndex = 0;
acl::json_node* node = body.first_node();
while (node)
{
if (node->tag_name())
{
std::string tagStr = std::string(node->tag_name());
std::string valStr = std::string(node->get_text());
valStr = UTF_82ASCII(valStr);//转换ASCII格式,方便显示输出
if ("title" == tagStr) {//标题
m_MutexNewsData.Lock();
newsData.push_back(valStr);
m_MutexNewsData.Unlock();
printf("tag: %s", node->tag_name());
if (!valStr.empty())
printf(", value: %s\r\n", valStr.c_str());
else
printf("\r\n");
}
}
node = body.next_node();
}
return true;
}
运行效果链接信息可参考聚合数据新闻API使用介绍页面的调试工具进行细节求证,下面给出我获取“top”新闻的标题信息输出显示
微信关注我们
转载内容版权归作者及来源网站所有!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。
为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。
Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。
Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。