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

个人网站要备案嘛重庆企业黄页大全电话

个人网站要备案嘛,重庆企业黄页大全电话,龙华网站优化,国际1688网站文章目录 1.HTTP概念2. URLurlencode 和 urldecode转义规则 3. HTTP的宏观理解HTTP的请求HTTP的响应 4. 见一见HTTP请求和响应请求报头 1. 模拟一个简单的响应response响应报头 2. 从路径中获取内容ReadFile函数的实现 3.不同资源进行区分反序列化的实现ReadOneLine函数的实现P… 文章目录 1.HTTP概念2. URLurlencode 和 urldecode转义规则 3. HTTP的宏观理解HTTP的请求HTTP的响应 4. 见一见HTTP请求和响应请求报头 1. 模拟一个简单的响应response响应报头 2. 从路径中获取内容ReadFile函数的实现 3.不同资源进行区分反序列化的实现ReadOneLine函数的实现ParseRequestLine函数的实现 路径path的最终表示 4. 同时显示 文字 和 图片GetContentType函数的实现 5.模拟的完整代码wwwrootindex.html(图片) Err.hpp(错误)HttpServer.hpp(初始化和启动)Log.hpp(日志)Main.cc(回调函数调用)makefileSock.hpp(TCP套接字)Until.hpp 1.HTTP概念 应用层 典型的 协议 HTTP(超文本传输协议) 它是应用最广泛的协议 作用为将任意内容拉取到本地浏览器让浏览器进行解释 客户端client 把自己的东西 给别人 同时也想把 别人的东西 拿到自己本地 一般称为 CS 模式 http中的网页文本 、图片 、视频、音频 统一称为资源 东西实际上就是资源 2. URL 要访问服务器就必须知道服务器的IP地址和端口号 需要有一个 域名解析服务 如: baidu.com (域名) 解析成 110.242.68.4(IP地址) 如QQ官网 https 作为协议 www.qq.com 作为服务器地址 server的端口号不能随意指定必须是众所周知且不能随便更改的 端口号和成熟的应用层协议是 一 一对应的 https 常用的端口号为443 http 常用的端口号为80 协议名称 和端口号之间是一对一 强相关 如附近着火了第一时间想起的就是打119 进行救火 由于http是超文本传输协议就需要告诉别人要访问什么资源 第一个 / 表示 web根目录 第二个 / 表示 路径分隔符 / / 表示 URL想访问服务器的 什么资源 ? 表示区分 URL 左侧 和右侧的分隔符 ? 后面跟的都是参数 参数是KV的 左边的 uid 可看作是K 右边的 1 可看作V URL 被称为 统一资源定位符 urlencode 和 urldecode 只搜索 ?/#: 这些特殊符号 发现特殊符号被转化为16进制格式数字 因为URL本身用一些字符作为特殊字符所以在使用特殊字符时所以特殊符号被转化为16进制格式数字用来和URL本身的特殊字符进行区分 转化的过程 被称之为 URL的 encode编码用于解决 URL中特殊符号的问题 这个工作是由浏览器或者客户端 自动做的服务器收到的就为 16进制格式而不想要16进制格式想要特殊符号 就需要进行 decode编码 转义规则 将需要转码的字符转为 16进制然后从右到左取4位(不足4位直接处理)每2位做一位前面加上%编码成%XY格式 点击查看自动编码工具 在该网站上可以进行 urlencode 与urlencode 解码 3. HTTP的宏观理解 HTTP的请求 按照完整的说法HTTP分为四部分 第一部分——请求行 HTTP的请求行以行为单位分为三部分 请求方法 URL 协议版本 请求方法 GET/ POST URL请求资源 协议版本http/1.0 http/1.1 http/2.0 三部分之间用空格作为分隔符把这三部分 分离开 第二部分——请求报头 由 Key:Value 所构成的多行结构 第三部分——空行 \r\n 第四部分——有效载荷 一般是用户可能提交的参数 (可以没有) HTTP的响应 状态行 分为 协议版本 状态码 状态码描述 三部分之间用空格作为分隔符把这三部分 分离开 协议版本http/1.0 http/1.1 http/2.0 状态码 如404 状态码描述 : 404所对应的含义 如Not Found 响应报头 也是 由Key:Value 所构成的多行结构 有效载荷 可能是 html /css的文件资源也可能是请求对应的图片等 4. 见一见HTTP请求和响应 请求报头 当从浏览器输入 主机IP端口号 Linux上显示如下数据 GET / HTTP/1.1 第一行作为 请求行 由 Key Value 构成的 多行结构 作为 请求报头 并没有包含 有效载荷 Host 表示 这次请求给哪台主机一般为目标服务器的IP地址和端口号 Connection 表示 这次请求的链接模式 长/短链接 Cache-control 表示 双方在通信时 要建立缓存最大缓存的生存时间默认为0(不缓存) User_Agent 表示 HTTP请求的客户端信息 Accept_Encodong 表示 作为客户端能接受的编码和压缩类型 Accept_Language 表示 作为客户端能接受编码符号 1. 模拟一个简单的响应response 创建一个Main.cc通过调用 回调函数HandlerHttp的方式来实现整个过程 对于回调函数 HandlerHttp在是一个完整的http请求报文的前提下分别将状态行 分隔符 有效载荷 添加到 response响应中并将 响应返回 有效载荷部分以网页部分呈现的 响应报头 进行文本分析时按行进行分割读取直到找到一行是空行则认为把报头读完了 报头中key 为 Content-Length Value 为 Body的长度(有效载荷的长度) 当在Linux上运行程序并输入端口号时 浏览器上 输入 主机IP端口号 就会使主函数 调用回调函数 打印 this a test 同时Linux会出现如下数据 响应的 状态行 响应报头 空行 有效载荷 由于有效载荷内部分为 图片、视频、音频 资源 为了便于区分 使用 Content_Type Body的种类 图片、视频、音频 资源 这些资源本质都是文件 图片的后缀为.png 网页的后缀为.html 视频的后缀为.mp3 Linux资源都要有自己的后缀需要告诉别人 就需要 Content-Type 对照表 若后缀为.html则 Content-Type 对照表 为 text/html 若后缀为.png则 Content-Type 对照表 为 image/png 在响应后 添加 网页的Content-Type 对照表 text/html以及 SEP分隔符 2. 从路径中获取内容 给http维护一个自己的目录即 wwroot 创建 index.html 里面放入这个网页中的所有资源 创建 Until.hpp 在Until这个类中创建一个接口 ReadFile 用于读取整个文件内容 第一个参数 path 为指定的路径 第二个参数file_content 表示输出 即文件对应的内容 path表示路径在wwwroot目录下的index.html中获取文件 将获取到的文件交给 字符串body ReadFile函数的实现 1. 获取文件本身的大小 输入 man 2 stat 对指定的文件路径获取它的struct stat 属性 成功返回0失败返回-1 st_size 表示这个文件 按字节为单位的大小 st_mode: 匹配很多的宏 2. 调整string的空间 保证能够把文件全部放下 开辟size大小个空间 3. 读取 O_RDONLY 读取 path作为路径可以找到对应 index.html的内容再将内容传给body字符串中作为有效载荷 3.不同资源进行区分 只有是请求无脑响应的都是这些资源 若请求到不同的资源应该加以区分 用户想要什么就给他什么没有就返回404 把request 进行处理进行反序列化由字符串信息变成结构化字段 创建一个 HttpRequest 结构体 里面包含 状态行的请求方法、URL、请求版本以及请求报头 URL作为请求资源所以将 path替换成 req.url_ 即可 反序列化的实现 在主函数Main.cc中 创建ReadOneLine函数将message中的第一行的请求行取出 创建 ParseRequestLine函数将 请求行解析成 请求方法、URL、协议版本 两个函数都在Util.hpp中实现 ReadOneLine函数的实现 加上static修饰是为了防止有隐藏的this指针存在 使用find函数寻找sep分隔符若找到则返回pos位置的下标 使用substr函数 取出[0,pos]区间的子串 作为返回值 使用 erase函数 将下标从0开始 删除 possep.size()个字符 ParseRequestLine函数的实现 sstream 流 按照空格作为分隔符打印到三个string中 路径path的最终表示 路径path是需要加上 web根目录的 所以定义一个web根目录 webRoot 在使用请求时先在路径path中 加入web根目录 再添加对应的 URL(请求资源) 4. 同时显示 文字 和 图片 点击查看:石榴花图片 在wwwroot中 创建 image文件并进入inmage中 wget 远程获取资源的命令 使用 wget 图片地址获取图片 使用 mv 指令 将 原图片名字改为 1.jpg 此时在vscode中的 image 文件中就可以显示图片了 一张网页包含很多要素资源如图片 文字 视频 每一个资源都要发起一次http请求 在浏览器中搜索 w3cschool 在HTML教程中找到HTML图像其中寻找到 替换文本属性 第一个/表示 web根目录 即wwwroot 在wwroot目录下找到image文件中的 1.jpg 若获取图片失败则会显示文字 这是一张石榴花图片 由于这次资源既包含文字 又包含图片所以类型不同需要处理 Content-Type (body的种类) 添加成员变量判断 要访问的是什么资源(如图片 文字) 在反序列化函数中 使用 rfind 函数 从后往前 查找 字符 . 再使用substr 函数 从下标 pos开始取len个字符 若没有给len则一直取到path_字符串结束 在HandlerHttp函数的 使用请求中 将 Content-Type (body的种类) 进行封装成 一个GetContentType的接口 GetContentType函数的实现 若后缀为.html则 Content-Type 对照表 为 text/html 若后缀为.css则 Content-Type 对照表 为 test/css 若后缀为.js则 Content-Type 对照表 为 application/x-javascript 若后缀为.png则 Content-Type 对照表 为 image/png 若后缀为.jpg则 Content-Type 对照表 为 image/jpeg 在浏览器 输入 主机IP端口号 发现图片并没有显示而且出现了乱码 网页必须指明编码格式否则就会出现乱码 所以修改index.html的内容 再次输入 主机IP 和端口号 就可以同时显示 文字 和图片了 5.模拟的完整代码 wwwroot index.html(图片) !DOCTYPE html html langenheadmeta charestUTF-8meta nameviewport contentwidthdevice-width ,initial-scale1.0titleDocument/title /headbodyh1this is a test /h1h1this is a test /h1h1this is a test /h1h1this is a test /h1img src/image/1.jpg alt这是一张石榴花图片 /body/html Err.hpp(错误) #pragma once enum {USAGE_ERR1,SOCKET_ERR,//2BIND_ERR,//3LISTEN_ERR,//4SETSID_ERR,//5OPEN_ERR//6 }; HttpServer.hpp(初始化和启动) #includeiostream #includestring #includepthread.h #includefunctional #includeSock.hppstatic const uint16_t defaultport8888;//默认端口号class HttpServer; //定义 func_t 类型 为 返回值为string 参数为string的包装器 using func_t std::functionstd::string( std::string);class ThreadData{public:ThreadData(int sock,std::string ip,const uint16_t port,HttpServer*tsvrp)//构造:_sock(sock),_ip(ip),_port(port),_tsvrp(tsvrp){}~ThreadData(){}public:int _sock;//套接字HttpServer *_tsvrp;//指针指向Tcp服务器 std::string _ip;uint16_t _port;};class HttpServer {public:HttpServer(func_t f,int port defaultport):func(f),port_(port){}void InitServer()//初始化{listensock_.Socket();//创建套接字listensock_.Bind(port_);//绑定listensock_.Listen();//监听}void HandlerHttpRequest(int sock)//{char buffer[4096];std::string request;//将套接字的数据读取到buffer中ssize_t srecv(sock,buffer,sizeof(buffer)-1,0);if(s0)//读取成功{buffer[s]0;//将\0赋值给buffer中requestbuffer;std::string response func(request);//回调函数 将request变为responsesend(sock,response.c_str(),response.size(),0);//发送 将respnse中的内容 发送到sock套接字中}else {//读取失败logMessage(Info,client quit ...);//打印日志 }} static void* threadRoutine(void *args){//线程分离 若不关心线程返回值 则提前告诉它 要进行分离pthread_detach(pthread_self());ThreadData* td(ThreadData*)args;td-_tsvrp-HandlerHttpRequest(td-_sock);close(td-_sock);delete td;return nullptr;}void Start()//启动{for(;;){std::string clientip;uint16_t clientport;int socklistensock_.Accept(clientip,clientport);//获取客户端IP和端口号if(sock0){continue;}pthread_t tid;ThreadData *td new ThreadData(sock,clientip,clientport,this);pthread_create(tid,nullptr,threadRoutine,td);}}~HttpServer(){}private:int port_; //端口号Sock listensock_;//套接字func_t func; //包装器类型的回调函数 }; Log.hpp(日志) #pragma once #includeiostream #includestring.h #includecstdio #includecstring #includecstdarg #includeunistd.h #includesys/types.h #includetime.hconst std::string filenametecpserver.log;//日志等级 enum{Debug0, // 用于调试Info , //1 常规Warning, //2 告警Error , //3 一般错误Tatal , //4 致命错误Uknown//未知错误 };static std::string tolevelstring(int level)//将数字转化为字符串 {switch(level){case Debug : return Debug;case Info : return Info;case Warning : return Warning;case Error : return Error;case Tatal : return Tatal;default: return Uknown;} } std::string gettime()//获取时间 {time_t currtime(nullptr);//获取time_tstruct tm *tmplocaltime(curr);//将time_t 转换为 struct tm结构体char buffer[128];snprintf(buffer,sizeof(buffer),%d-%d-%d %d:%d:%d,tmp-tm_year1900,tmp-tm_mon1,tmp-tm_mday,tmp-tm_hour,tmp-tm_min,tmp-tm_sec);return buffer;} void logMessage(int level, const char*format,...) {//日志左边部分的实现char logLeft[1024];std::string level_stringtolevelstring(level);std::string curr_timegettime();snprintf(logLeft,sizeof(logLeft),%s %s %d,level_string.c_str(),curr_time.c_str());//日志右边部分的实现char logRight[1024]; va_list p;//p可以看作是1字节的指针va_start(p,format);//将p指向最开始vsnprintf(logRight,sizeof(logRight),format,p);va_end(p);//将指针置空//打印日志 printf(%s%s\n,logLeft,logRight);//保存到文件中FILE*fpfopen( filename.c_str(),a);//以追加的方式 将filename文件打开//fopen打开失败 返回空指针if(fpnullptr){return;}fprintf(fp,%s%s\n,logLeft,logRight);//将对应的信息格式化到流中fflush(fp);//刷新缓冲区fclose(fp); } Main.cc(回调函数调用) #includevector #includememory #includeHttpServer.hpp #includeUtil.hppusing namespace std; const std::string SEP\r\n;const std::string defaultHomePage index.html;//默认首页 const std::string webRoot./wwwroot;//web根目录class HttpRequest { public:HttpRequest():path_(webRoot){}~HttpRequest(){}void Print(){logMessage(Debug,method:%s,url:%s,version:%s,method_.c_str(),url_.c_str(),httpVersion_.c_str());/*for(const autoline:body_){logMessage(Debug,-%s,line.c_str());}*/logMessage(Debug,path:%s,path_.c_str());logMessage(Debug,suffix:%s,suffix_.c_str());} public:std::string method_;//请求方法std::string url_; //URLstd::string httpVersion_;//请求版本std::vectorstd::string body_;//请求报头std::string path_; //想要访问的资源std::string suffix_;//后缀 用于判断访问是什么资源 };//反序列化 将字符串转化为 HttpRequest结构体 HttpRequest Deserialize(std::string message) {HttpRequest req;std::string lineUtil::ReadOneLine(message,SEP);//在message中根据分隔符读走状态行//将请求行分为 请求方法 URL 协议版本Util::ParseRequestLine(line,req.method_,req.url_,req.httpVersion_);//解析请求行logMessage(Info,method:%s,url:%s,version:%s,req.method_.c_str(),req.url_.c_str(),req.httpVersion_.c_str());//将状态行处理后剩余请求报头每一次取一行 将其放入body中while(!message.empty()){lineUtil::ReadOneLine(message,SEP);req.body_.push_back(line);}req.path_ req.url_; //path_在构造时已经默认为web根目录了所以只需加上资源即可//只有一个/需加上默认首页if(req.path_[req.path_.size()-1]/){req.path_ defaultHomePage;}auto posreq.path_.rfind(.);if( posstd::string::npos)//没找到{ req.suffix_.html;//默认为html}else {req.suffix_req.path_.substr(pos);}return req; }std::string GetContentType(std::string suffix)//判断是哪一种资源的后缀 {std::string content_type Content-Type: ;if(suffix.html|| suffix.htm){content_typetext/html;}else if(suffix.css ){content_typetext/css;}else if(suffix.js){content_typeapplication/x-javascript;}else if(suffix.png){content_typeimage/png;}else if(suffix.jpg){content_typeimage/jpeg;}else {}return content_typeSEP; } std::string HandlerHttp( std::string message)//回调函数的实现 {//1.读取请求//request 一定是一个完整的http请求报文//给别人返回的 http responsecout---------------------------endl;//2.反序列化和分析请求HttpRequest req Deserialize(message);req.Print();//3.使用请求std::string body;//有效载荷Util::ReadFile(req.path_,body);//将path路径中的内容交给body字符串中//做一次响应 //状态行 : 协议版本 状态码 状态码描述//200表示请求是正确的std::string responseHTTP/1.0 200 OKSEP;//状态码//Content-Length获取有效载荷长度responseContent-Length: std::to_string(body.size())SEP;//响应报头responseGetContentType(req.suffix_);response SEP; //分隔符response body; //有效载荷 return response; }int main(int argc,char* argv[]){ if(argc!2){exit(USAGE_ERR);}uint16_t portatoi(argv[1]);std::unique_ptrHttpServer tsvr(new HttpServer(HandlerHttp,port));tsvr-InitServer();tsvr-Start();return 0; } makefile httserver:Main.ccg -o $ $^ -stdc11 -lpthread .PHONY:clean clean:rm -f httserverSock.hpp(TCP套接字) #includeiostream #includecstring #includecstdlib #includenetinet/in.h #includearpa/inet.h #includesys/socket.h #includeunistd.h #includeLog.hpp #includeErr.hppstatic const int gbacklog32; static const int defaultfd-1; class Sock {public:Sock() //构造:_sock(defaultfd){}void Socket()//创建套接字{_socksocket(AF_INET,SOCK_STREAM,0);if(_sock0)//套接字创建失败{logMessage( Tatal,socket error,code:%s,errstring:%s,errno,strerror(errno));exit(SOCKET_ERR);}}void Bind(uint16_t port)//绑定{struct sockaddr_in local;memset(local,0,sizeof(local));//清空local.sin_familyAF_INET;//16位地址类型local.sin_port htons(port); //端口号local.sin_addr.s_addr INADDR_ANY;//IP地址//若小于0则绑定失败if(bind(_sock,(struct sockaddr*)local,sizeof(local))0){logMessage( Tatal,bind error,code:%s,errstring:%s,errno,strerror(errno));exit(BIND_ERR);}}void Listen()//将套接字设置为监听状态{//小于0则监听失败if(listen(_sock,gbacklog)0){logMessage( Tatal,listen error,code:%s,errstring:%s,errno,strerror(errno));exit(LISTEN_ERR);}}int Accept(std::string *clientip,uint16_t * clientport)//获取连接{struct sockaddr_in temp;socklen_t lensizeof(temp);int sockaccept(_sock,(struct sockaddr*)temp,len);if(sock0){logMessage(Warning,accept error,code:%s,errstring:%s,errno,strerror(errno));}else {//inet_ntoa 4字节风格IP转化为字符串风格IP*clientip inet_ntoa(temp.sin_addr) ; //客户端IP地址//ntohs 网络序列转主机序列*clientport ntohs(temp.sin_port);//客户端的端口号}return sock;//返回新获取的套接字}int Connect(const std::stringserverip,const uint16_t serverport )//发起链接{struct sockaddr_in server;memset(server,0,sizeof(server));//清空server.sin_familyAF_INET;//16位地址类型server.sin_porthtons(serverport);//端口号//inet_addr 字符串风格IP转化为4字节风格IPserver.sin_addr.s_addrinet_addr(serverip.c_str());//IP地址//成功返回0失败返回-1return connect(_sock, (struct sockaddr*)server,sizeof(server));}int Fd(){return _sock;}void Close(){if(_sock!defaultfd){close(_sock);}}~Sock()//析构{}private:int _sock;}; Until.hpp #pragma once #includeiostream #includestring #includesys/types.h #includesys/stat.h #includeunistd.h #includefcntl.h #includesstream #includeLog.hppclass Util {public:static bool ReadFile(const std::string path,std::string *fileContent )//读取整个文件内容{//1.获取文件本身的大小struct stat st;//定义一个struct stat 类型的结构体int nstat(path.c_str(),st);if(n0)//读取失败{return false;}int size st.st_size;//2.调整string的空间fileContent-resize(size); //3.读取int fdopen(path.c_str(),O_RDONLY);if(fd0)//读取失败{return false;}read(fd,(char*)fileContent-c_str(),size);//从文件fd中读取放到fileContentclose(fd);logMessage( Info,read file %s done ,path.c_str());return true;}//在message中根据分隔符取出状态行static std::string ReadOneLine( std:: string message,const std::string sep){auto posmessage.find(sep);//查找sep分隔符,找到则返回pos位置的下标while(posstd::string::npos)//没找到{return ;}std::string smessage.substr(0,pos);//取[0,pos]区间作为子串message.erase(0,possep.size());从下标为0处开始 删除possep.size()个字符return s;}//将请求行分解析为 请求方法 URL 协议版本static bool ParseRequestLine(const std::string line,std::string * method,std::string *url,std::string *httpVersion){//以空格为单位对内容做提取std::stringstream ss(line);ss *method *url *httpVersion;return true;}};
http://www.pierceye.com/news/493261/

相关文章:

  • 网站收录地址旅游网站建设的相关报价
  • seo月薪seo优化方法网站快速排名推广渠道
  • 企业网站设计理念如何seo网站
  • 河南移动商城网站建设怎么创建平台卖自己的产品
  • 网上做网站钱被骗了报案有用吗文章自定义wordpress
  • 网站设置成灰色市场监督管理局是什么单位
  • 北京国贸网站建设wordpress需要付费才能看某些页面
  • 郸城网站建设wordpress教程cms
  • 做本地网站赚钱吗?php网站制作过程中遇到的问题及解决办法
  • 上海网站快速排名提升ui是网站建设吗
  • 中信建设有限责任公司洪波seo外链工具
  • 网站服务器和空间有什么区别网站制作的公司哪家效果好
  • 做网站具体收费梅州南站
  • 淘宝禁止了网站建设类wordpress极速优化
  • 山东app网站制作网站建设优化广告流量
  • 做阿里云网站浏览器编程语言
  • 青岛市网站制作企业邮箱密码忘了怎么重置密码
  • 文交所网站开发和业务多一样的平台
  • 如何免费自己做网站wordpress成品图
  • thinkphp做中英文网站电子商务网站建设的步骤一般为
  • 网站编程 mysql小说关键词搜索器
  • 农业网站开发企业名录搜索软件免费
  • 临沂医院手机网站建设上饶专业做网站建设
  • 超酷html5效果的工作室网站程序宝洁网站建设
  • 网销的网站建设与管理曲阜市网站建设
  • 类似一起做网站的网站珠海网站建设王道下拉強
  • wordpress 当前文章id益阳网站seo
  • 湖南对外建设集团网站成都著名网站
  • 手机网站制作的公司wordpress分类目录添加图片
  • 做彩票网站需要多少钱网络营销和传统营销的关系