当前位置: 首页 > news >正文

一个基本的http客户端

高可用 客户端

1. httpClient.h

#include <iostream>
#include <string>
#include <functional>class HttpClient
{
public:HttpClient(std::string url) : url_(url), port_(0) {}int write_http(const std::string &method, const std::string &msg);private:int get_socket();int set_sock_timeout(int sockfd, int sec, int ms);int set_buf_size(int sockfd, int sendsize, int recvsize);int domain_judge(const char *buf);int split_url(std::string &url, std::string &host, unsigned short &port);int host_get_by_name(const char *name);void print_netstat(int err);int noblock_connect(int sockfd, struct sockaddr *addrs, int addrlen);int make_http_head(const char *method, std::string &httpmsg, const std::string &purl);int make_http_msg(const std::string &method, std::string &msg);int writen(int connfd, const char *vptr, size_t n);int recvn_timeout(int connfd, char *vptr, int n, int timeout);std::string readn(int sockfd, size_t n);int parse_recvmsg(std::string &recvmsg);int parse_test(std::string &msg);private:std::function<int(std::string &)> parseFunc_;std::string url_;std::string host_;unsigned short port_;
};

2.httpClient.cpp

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <memory>#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <netdb.h>
#include <unistd.h>
#include <sys/ioctl.h>#include <jsoncpp/json/json.h>#include "httpClient.h"int HttpClient::make_http_head(const char *method, std::string &httpmsg, const std::string &purl)
{char headbuf[1024] = {0};int len = snprintf(headbuf, sizeof(headbuf), "%s %s HTTP/1.1\r\n""Content-Type: application/json\r\n""Accept: application/json\r\n""Host: %s:%d\r\n""Connection: Keep-Alive\r\n""Content-Length: %d\r\n\r\n",method,purl.c_str(),host_.c_str(),port_,static_cast<int>(httpmsg.size()));httpmsg = headbuf + httpmsg;return 0;
}int HttpClient::make_http_msg(const std::string &method, std::string &msg)
{return make_http_head(method.c_str(), msg, "");
}int HttpClient::writen(int connfd, const char *vptr, size_t n)
{int nleft = n, nwrite = 0, retryCont = 0;char *ptr = const_cast<char *>(vptr);while (nleft > 0){if ((nwrite = send(connfd, ptr, nleft, MSG_NOSIGNAL)) <= 0){if (retryCont < 100 && (nwrite == 0 || errno == EINTR)){nwrite = 0;++retryCont;usleep(10000);}else{return -1;}}nleft -= nwrite;ptr += nwrite;}return n;
}int HttpClient::recvn_timeout(int connfd, char *vptr, int n, int sec)
{int nleft = n;int nread = 0, retryCnt = 0;char *ptr = vptr;fd_set fdset;struct timeval timeout;while (nleft > 0){timeout.tv_sec = sec;timeout.tv_usec = 0;FD_ZERO(&fdset);FD_SET(connfd, &fdset);if (select(connfd + 1, &fdset, nullptr, nullptr, &timeout) <= 0){printf("select fail errno = %d\n", errno);break;}if ((nread = recv(connfd, ptr, nleft, 0)) < 0){if (retryCnt < 50 && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)){nread = 0;++retryCnt;usleep(10000);}else{break;}}else if (nread == 0){break;}nleft -= nread;ptr += nread;}return (n - nleft);
}std::string HttpClient::readn(int sockfd, size_t n)
{char buf[2048] = {0};std::string result;int total = 0;int byterecv;do{byterecv = recvn_timeout(sockfd, buf, 2048, 5);if (byterecv <= 0){break;}total += byterecv;result.append(buf, byterecv);} while (total < n && byterecv == sizeof(buf));return result;
}int HttpClient::parse_recvmsg(std::string &recvmsg)
{std::string ::size_type headend = recvmsg.find("\r\n\r\n");if (headend == std::string::npos){std::cout << "not found header" << std::endl;return false;}std::string body = recvmsg.substr(headend + 4);return parseFunc_(body);
}int HttpClient::split_url(std::string &url, std::string &host, unsigned short &port)
{if (!url.compare(0, 7, "http://")){url = url.substr(7);}if (!url.compare(0, 8, "https://")){url = url.substr(8);}size_t slashPos = url.find("/");if (slashPos != std::string::npos){url = url.substr(0, slashPos);}size_t colonPos = url.find(":");if (colonPos == std::string::npos){host = url;port = 80;}else{host = url.substr(0, colonPos);port = atoi(url.substr(colonPos + 1).c_str());}
}int HttpClient::domain_judge(const char *buf)
{if (nullptr == buf){return false;}bool hasChar = false, hasDot = false;for (size_t i = 0; i < strlen(buf); ++i){if (isalpha(buf[i])){hasChar = true;continue;}if ('.' == buf[i]){hasDot = true;continue;}if (hasChar && hasDot){return true;}}return false;
}int HttpClient::host_get_by_name(const char *name)
{//    char ipaadress[64] = {0};struct addrinfo hints, *reslut = nullptr, *address = nullptr;memset(&hints, 0, sizeof(addrinfo));hints.ai_family = AF_UNSPEC; // ipv4 ipv6hints.ai_flags = AI_PASSIVE;hints.ai_socktype = SOCK_STREAM;int ret = getaddrinfo(name, nullptr, &hints, &reslut);if (ret != 0){std::cerr << "getaddrinfo err " << gai_strerror(ret) << std::endl;return ret;}for (address = reslut; address != nullptr; address = address->ai_next){if (address->ai_family == AF_INET){struct sockaddr_in *addr = reinterpret_cast<struct sockaddr_in *>(address->ai_addr);freeaddrinfo(reslut);return static_cast<int>(addr->sin_addr.s_addr);}else if (address->ai_family == AF_INET6){struct sockaddr_in6 *addr = reinterpret_cast<struct sockaddr_in6 *>(address->ai_addr);continue; // 暂不使用ipv6}}freeaddrinfo(reslut);return false;
}int HttpClient::set_buf_size(int sockfd, int sendsize, int recvsize)
{int ret1 = ::setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, reinterpret_cast<char *>(&sendsize), sizeof(sendsize));int ret2 = ::setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, reinterpret_cast<char *>(&recvsize), sizeof(recvsize));return (ret1 == 0 && ret2 == 0) ? 0 : -1;
}int HttpClient::set_sock_timeout(int sockfd, int sec, int ms)
{timeval timeout = {sec, ms * 1000};int ret1 = ::setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<char *>(&timeout), sizeof(timeout));int ret2 = ::setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, reinterpret_cast<char *>(&timeout), sizeof(timeout));return (ret1 == 0 && ret2 == 0) ? 0 : -1;
}int HttpClient::noblock_connect(int sockfd, struct sockaddr *addrs, int addrlen)
{struct timeval timeout = {5, 0};int err = -1;fd_set fdset;int flag = 1;if (ioctl(sockfd, FIONBIO, &flag) != 0){printf("ioctl error\n");}int ret = connect(sockfd, addrs, addrlen);if (-1 == ret){if (EINPROGRESS == errno){FD_ZERO(&fdset);FD_SET(sockfd, &fdset);if (select(sockfd + 1, nullptr, &fdset, nullptr, &timeout) > 0){getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &err, (socklen_t *)&addrlen);if (0 == err){ret = 0;}else{ret = -1;}}else{ret = -1;}}}flag = 0;if (ioctl(sockfd, FIONBIO, &flag) != 0){printf("ioctl error\n");}if (ret < 0){print_netstat(err);}return ret;
}void HttpClient::print_netstat(int err)
{switch (err){case ENETUNREACH: // 网不通case EHOSTUNREACH:printf("network is unreachable err[%d]\n", err);break;case ECONNREFUSED: // 连接端口被拒绝printf("no-one listening on the remote address\n");break;case ETIMEDOUT: // 网络连接失败,服务器未响应printf("timeout while attempting connection the server may be to busy\n");break;default:printf("other errno %d\n", err);break;}
}int HttpClient::get_socket()
{int bufsize = 0x20000; // 128kint errnoret = -1;struct sockaddr_in serveraddr;int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0){return -1;}memset(&serveraddr, 0, sizeof(serveraddr));serveraddr.sin_family = AF_INET;split_url(url_, host_, port_);if (domain_judge(host_.c_str())){serveraddr.sin_addr.s_addr = host_get_by_name(host_.c_str());}else{serveraddr.sin_addr.s_addr = inet_addr(host_.c_str());}serveraddr.sin_port = htons(port_);if (set_buf_size(sockfd, bufsize, bufsize) < 0){close(sockfd);return -1;}if (set_sock_timeout(sockfd, 5, 0) < 0){close(sockfd);return -1;}int ret = noblock_connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));if (-1 == ret){close(sockfd);return -1;}return sockfd;
}int HttpClient::parse_test(std::string &msg)
{std::cout << msg << std::endl;return 0;
}int HttpClient::write_http(const std::string &method, const std::string &msg)
{std::string httpmsg = msg;int fd = get_socket();if (fd < 0){printf("fd is error\n");return -1;}make_http_msg(method, httpmsg);writen(fd, httpmsg.c_str(), httpmsg.size());std::string recvmsg = readn(fd, 2048);std::cout << recvmsg << std::endl;if (recvmsg.size()){parseFunc_ = std::bind(&HttpClient::parse_test, this, std::placeholders::_1);parse_recvmsg(recvmsg);}return 0;
}void test()
{HttpClient client("192.168.95.1:8080");client.write_http("post", "hello\n");
}int main()
{test();return 0;
}

相关文章:

一个基本的http客户端

高可用 客户端 1. httpClient.h #include <iostream> #include <string> #include <functional>class HttpClient { public:HttpClient(std::string url) : url_(url), port_(0) {}int write_http(const std::string &method, const std::string &…...

html-网站菜单-点击菜单展开相应的导航栏,加减号可切换

一、效果图 1.点击显示菜单栏&#xff0c;点击x号关闭&#xff1b; 2.点击一级菜单&#xff0c;展开显示二级&#xff0c;并且加号变为减号&#xff1b; 3.点击其他一级导航&#xff0c;自动收起展开的导航。 二、代码实现 <!DOCTYPE html> <html><head>&…...

2.FastRunner定时任务Celery+RabbitMQ

注意&#xff1a;celery版本和Python冲突问题 不能用高版本Python 用3.5以下&#xff0c;因为项目的celery用的django-celery 3.2.2 python3.7 async关键字 冲突版本 celery3.x方案一&#xff1a; celery3.xpython3.6方案二 &#xff1a; celery4.xpython3.7 解决celery执…...

vb.net 实时监控双门双向门禁控制板源代码

本示例使用设备介绍&#xff1a;实时网络双门双向门禁控制板可二次编程控制网络继电器远程开关-淘宝网 (taobao.com) Imports System.Net.Sockets Imports System.Net Imports System.Text Imports System.ThreadingImports System.Net.NetworkInformation Imports System.Man…...

文具办公产品展示预约小程序的作用如何

从整体来看&#xff0c;文具办公品牌/门店的生意来源于线下自然流量或线上自营商城/入驻第三方商城的的流量&#xff0c;线上多数情况都是以直接销售配送为主&#xff0c;但其实对文具品牌/门店而言还有信息展示、服务预约、在线咨询、产品介绍等需求。 虽然小区周边的消费者需…...

渗透测试流程是什么?7个步骤给你讲清楚!

在学习渗透测试之初&#xff0c;有必要先系统了解一下它的流程&#xff0c;静下心来阅读一下&#xff0c;树立一个全局观&#xff0c;一步一步去建设并完善自己的专业领域&#xff0c;最终实现从懵逼到牛逼的华丽转变。渗透测试是通过模拟恶意黑客的攻击方法&#xff0c;同时也…...

如何解决网站被攻击的问题:企业网络攻防的关键路径

在当今数字化时代&#xff0c;企业面临着不断升级的网络威胁&#xff0c;网站遭受攻击的风险也与日俱增。解决网站被攻击的问题对企业发展至关重要&#xff0c;不仅关系到企业的信息安全&#xff0c;也直接影响到企业的声誉和利益。从企业发展的角度出发&#xff0c;我们将探讨…...

大健康产业的先行者「完美公司」携手企企通,推进企业采购供应链数字化进程

随着中国经济持续向好&#xff0c;消费升级和美妆步骤增加&#xff0c;美妆和个人护理产品已逐渐成为中国消费者的日用消费品&#xff0c;推动了护肤品和化妆品的销售额增速均超过10%&#xff0c;成为中国整个快速消费品市场中的一颗亮眼明珠。 据国家统计局数据显示&#xff0…...

在windows Server安装Let‘s Encrypt的SSL证书

1、到官网&#xff08;https://certbot.eff.org/instructions?wswebproduct&oswindows&#xff09;下载 certbot客户端。 2、安装客户端&#xff08;全部默认安装即可&#xff09; 3、暂停IIS中的网站 开始菜单中找到并运行“Certbot”&#xff0c;输入指令&#xff1a; …...

GPT实战系列-P-Tuning本地化训练ChatGLM2等LLM模型,到底做了什么?(二)

GPT实战系列-如何使用P-Tuning本地化训练ChatGLM2等LLM模型&#xff1f;(二) 文章目录 GPT实战系列-1.训练参数配置传递2.训练前准备3.训练参数配置4.训练对象&#xff0c;seq2seq训练5.执行训练6.训练模型评估依赖数据集的预处理 P-Tuning v2 将 ChatGLM2-6B 模型需要微调的参…...

Python3.7+PyQt5 pyuic5将.ui文件转换为.py文件、Python读取配置文件、生成日志

1.实际开发项目时&#xff0c;是使用Qt Designer来设计UI界面&#xff0c;得到一个.ui的文件&#xff0c;然后利用PyQt5安装时自带的工具pyuic5将.ui文件转换为.py文件&#xff1a; pyuic5 -o mywindow.py mywindow.ui #先是py文件名&#xff0c;再是ui文件名样式图 QT5 UI&am…...

使用 VPN ,一定要知道的几个真相!

你们好&#xff0c;我的网工朋友。 今天想和你聊聊VPN。在VPN出现之前&#xff0c;企业分支之间的数据传输只能依靠现有物理网络&#xff08;例如Internet&#xff09;。 但由于Internet中存在多种不安全因素&#xff0c;报文容易被网络中的黑客窃取或篡改&#xff0c;最终造…...

数电实验-----实现74LS153芯片扩展为8选1时间选择器以及应用(Quartus II )

目录 一、74LS153芯片介绍 管脚图 功能表 二、4选1选择器扩展为8选1选择器 1.扩展原理 2.电路图连接&#xff08;Quartus II &#xff09; 3.仿真结果 三、8选1选择器的应用 1.三变量表决器 2.奇偶校验电路 一、74LS153芯片介绍 74ls153芯片是属于四选一选择器的芯片。…...

如何实现MATLAB与Simulink的数据交互

参考链接&#xff1a;如何实现MATLAB与Simulink的数据交互 MATLAB是一款强大的数学计算软件&#xff0c;Simulink则是一种基于模型的多域仿真平台&#xff0c;常用于工程和科学领域中的系统设计、控制设计和信号处理等方面。MATLAB和Simulink都是MathWorks公司的产品&#xff0…...

【数据结构】归并排序

​​ &#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;数据结构 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵 希望大佬指点一二 如果文章对你…...

数字引领,智慧赋能|袋鼠云与易知微共同亮相2023智慧港口大会

2023年10月19日&#xff0c;由中国港口协会、中国交通通信信息中心、天津港&#xff08;集团&#xff09;有限公司主办&#xff0c;中国港口协会智慧港口专业委员会、《港口科技》杂志社等单位承办的以“数字引领 智慧赋能”为主题的“2023智慧港口大会”在天津顺利召开。 袋鼠…...

星火模型(Spark)的langchain 实现

星火模型的langchain实现 测试已通过&#xff0c;希望有所帮助。 使用前请先安装环境&#xff1a; pip install githttps://github.com/shell-nlp/spark-ai-python.git注意&#xff1a; 一定要使用上面方式安装spark库&#xff0c;因对官方的库做了改动。官方的库已经长时间不…...

python运算符重载之构造函数和迭代器

1 python运算符重载之构造函数和迭代器 python运算符重载是在类方法中拦截内置操作-当类的实例使用内置操作时&#xff0c;pytho自动调用对应方法&#xff0c;并且返回操作结果。 NO#描述1拦截运算运算符重载拦截内置操作&#xff0c;比如打印、函数调用、点号运算、表达式运…...

【数据处理】Python:实现求条件分布函数 | 求平均值方差和协方差 | 求函数函数期望值的函数 | 概率论

猛戳订阅! 👉 《一起玩蛇》🐍 💭 写在前面:本章我们将通过 Python 手动实现条件分布函数的计算,实现求平均值,方差和协方差函数,实现求函数期望值的函数。部署的测试代码放到文后了,运行所需环境 python version >= 3.6,numpy >= 1.15,nltk >= 3.4,tqd…...

new/delete 和malloc/free的区别

C中&#xff1a; 创建单个数据空间&#xff1a; char *ch new char; delete ch; ch NULL; 创建多个数据空间&#xff1a; char *ch new char[4]; delete [] ch; ch NULL; C语言中&#xff1a; 创建单个数据空间&#xff1a; char *ch malloc(sizeof(char)); fre…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

Spring AI与Spring Modulith核心技术解析

Spring AI核心架构解析 Spring AI&#xff08;https://spring.io/projects/spring-ai&#xff09;作为Spring生态中的AI集成框架&#xff0c;其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似&#xff0c;但特别为多语…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣&#xff08;LeetCode&#xff09; ​遍历字符串​&#xff1a;通过外层循环逐一检查每个字符。​遇到 ? 时处理​&#xff1a; 内层循环遍历小写字母&#xff08;a 到 z&#xff09;。对每个字母检查是否满足&#xff1a; ​与…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...