目录

一、套接字接口类封装

二、服务器实现

三、实现效果


一、套接字接口类封装

#include<iostream>
#include<string>
#include<vector>
#include<unistd.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/socket.h>//封装TCPsocket类
#define MAX_LISTEN 5
#define CHECK_RETURN(X) if((X) == false) {return -1;}class TCPsocket {private:int _sockfd;public:TCPsocket () : _sockfd(-1) {}//1.创建套接字bool Socket() {_sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (_sockfd < 0) {perror("create socket error!");return false;}return true;} //2.为套接字绑定地址信息bool Bind(const std::string &ip, uint16_t port) {struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr(ip.c_str());socklen_t len = sizeof(struct sockaddr_in);int ret = bind(_sockfd, (struct sockaddr*)&addr, len);if (ret < 0) {perror("bind error!");return false;}return true;}//客户端:3.向服务器发起连接请求bool Connect(const std::string &ip, uint16_t port) {struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr(ip.c_str());socklen_t len = sizeof(struct sockaddr_in);int ret = connect(_sockfd, (struct sockaddr*)&addr, len);if (ret < 0) {perror("connect error!");return false;}return true;}//服务端:3.开始监听bool Listen(int backlog = MAX_LISTEN) {int ret = listen(_sockfd, backlog);if (ret < 0) {perror("connect error!");return false;}return true;}//服务端:4. 获取新建连接bool Accept(TCPsocket *sock, std::string *ip = NULL, uint16_t *port = NULL) {struct sockaddr_in addr;socklen_t len = sizeof(struct sockaddr_in);int newfd = accept(_sockfd, (struct sockaddr*)&addr, &len);if (newfd < 0) {perror("accept error!");return false;}sock -> _sockfd = newfd;if (ip != NULL) *ip = inet_ntoa(addr.sin_addr);if (port != NULL) *port = ntohs(addr.sin_port);return true;}//4. 接收数据bool Recve(std::string *body) {char temp[8193] = {0};int ret = recv(_sockfd, temp, 8192, 0);if (ret < 0) {perror("recve error!");return false;}else if (ret == 0) {std::cout<<"peer shutdown!"<< std::endl;return false;}body -> assign(temp, ret);return true;}//5.发送数据bool Send(const std::string &body) {int ret = send(_sockfd, body.c_str(), body.size(), 0);if (ret < 0) {perror("send error!");return false;}return true;}//6.关闭套接字bool Close() {if (_sockfd != -1) close(_sockfd);return true;}
};

二、服务器实现

#include "socket_tcp.hpp"
#include <sstream>int main(int argc, char *argv[]) {if (argc != 2) {std::cout<<"./http_server  port"<< std::endl;return -1;}int srv_port = std::stoi(argv[1]);std::string srv_ip = "0.0.0.0";TCPsocket sock;//1.创建套接字CHECK_RETURN(sock.Socket());//2.绑定地址信息CHECK_RETURN(sock.Bind(srv_ip, srv_port));//3.开始监听CHECK_RETURN(sock.Listen());while(1) {TCPsocket new_sock;bool ret = sock.Accept(&new_sock);//4.获取新建连接if (ret == false) continue;//5.收发数据std::string rec;new_sock.Recve(&rec);size_t pos = rec.find("\r\n\r\n");//查找头部结尾标志if (pos == std::string::npos) {//没有找到,则认为头部过大//将响应状态码设置为414//这里简单实现,就直接错误返回了return -1;}std::string header = rec.substr(0,pos);//截取头部std::string body = rec.substr(pos + 4);//截取正文//正常的截图正文,应该将头部按照\r\n进行分割,逐个取出头部;//然后根据头部中的Content-Length确定正文长度,正文长度= rec.size() - header.size() - 4;//然后在截取正文std::cout<<"header:[" << body << "]" << std::endl;std::cout<< "body:[" << body << "]" << std::endl;//响应std::string rep_body = "<html><body><h1>Hello world!</h1></body></html>";std::stringstream ss_reply;ss_reply << "HTTP/1.1 200 OK\r\n";ss_reply << "Connection: close\r\n";ss_reply << "Content-Type: text/html\r\n";ss_reply << "Content-Length: " << rep_body.size() << "\r\n";ss_reply << "\r\n";ss_reply << rep_body;std::cout << "response:[" << ss_reply.str() << "]" << std::endl;new_sock.Send(ss_reply.str());//短连接,完成响应,关闭连接new_sock.Close();}//6.关闭套接字sock.Close();return 0;
}

三、实现效果

1.运行服务端

2.在浏览器输入URL进行请求获取响应

实现简易HTTP服务器相关推荐

  1. python3编写简易统计服务器

    打点这个功能总是美其名曰"帮助提升用户体验",其实说白了就是记录用户做了哪些操作.目前国内很多通用软件都做了相关功能,像360.QQ等这样的以用户体验出众的软件,其打点的面自然也很 ...

  2. RHEL5系统 sendmail+qpopper 架设简易邮件服务器

    转自 "小蜗牛技术之家" 博客  原稿: http://snailwarrior.blog.51cto.com/680306/139098 [小蜗牛奋力之作 ] 目标:在RHEL5 ...

  3. python 简易HTTP服务器搭建

    安装Python简易HTTP服务器 大多数Linux/Unix/mac OS操作系统都已默认安装,直接运行以下命令即可,其中"8008"为指定的端口号:如果没有安装python,可 ...

  4. cefsharp 发送请求服务器_使用 WPF 版简易 SIP 服务器向 GB28181 摄像头发送直播请求...

    使用 WPF 版简易 SIP 服务器向 GB28181 摄像头发送直播请求 目录 一.引言 二.项目渊源 三.软件使用及 SIP INVITE 流程 (一) 注册和心跳 (二) 直播 INVITE 四 ...

  5. PHP服务器脚本实例,Shell脚本实现的一个简易Web服务器例子分享_linux shell

    这篇文章主要介绍了Shell脚本实现的一个简易Web服务器例子分享,本文实现的Web服务器非常简单实用,可以在你不想安装nginx.apache等大型WEB服务器时使用,需要的朋友可以参考下 假设你想 ...

  6. python局域网大文件_[源码]Python简易http服务器(内网渗透大文件传输含下载命令)...

    Python简易http服务器源码 import SimpleHTTPServer import SocketServer import sys PORT = 80 if len(sys.argv) ...

  7. Socket 简易静态服务器 WPF MVVM模式(一)

    整体代码下载 主要实现功能: Socket的简单应用 可修改IP和端口 显示来访信息 界面设计: 界面采用MVVM设计,很简陋. 前台的主要目的是 输入IP地址 输入端口 输入文件目录 开启监听和停止 ...

  8. 使用bind构建本地简易dns服务器

    本篇博客主要介绍如何在linux上构建简易dns服务器,内容涵盖本地dns解析,主从dns服务器区域传送.rndc的使用以及如何在主域中添加子域 说明: 本实验操作均在VMware10上实现,需要准备 ...

  9. 本地计算机架设http服务器,Http File Server(简易Http服务器服务端)

    如果您感觉配置IIS和apache等web服务端太麻烦的话,不妨试试Http File Server,Http File Server是一套简易的Http服务器服务端系统,它无需安装,运行后简单配置一 ...

  10. node.js搭建简易Web服务器

    node.js搭建简易Web服务器 node.js简介 Node.js 是一个基于V8引擎的JavaScript 运行环境. V8 是为Google Chrome 提供支持的 JavaScript 引 ...

最新文章

  1. bitbucket迁移
  2. 深入理解 HTTPS
  3. 事故通报绝不能一报了事22344
  4. 船体6自由度英文名称
  5. Java ObjectOutputStream flush()方法与示例
  6. linux lib目录找不到,linux中jpeglib库文件我安装了,但是我运行自己写的代码总是找不到这个库...
  7. 创龙DSP6748开发板驱动LCD屏
  8. 最后一届90后毕业了 超485万人在抖音发布毕业视频
  9. PetShop之表示层设计
  10. RPM 打包指南系列 一
  11. 2017年云南职称计算机考试,云南省2017年职称计算机考试内容及考试方式
  12. 职业技能鉴定准考证打印系统
  13. Win2003安全警报--当前安全设置不允许从该位置下载文件
  14. workbook对象需要关闭_jxl读取excel需要关闭Workbook?
  15. 《老爸老妈浪漫史》Barney和Robin终于。。。
  16. JS 控制LPT1 直接打印!
  17. uboot启动流程详细分析(基于i.m6ull)
  18. 精品微信小程序校园第二课堂在线学习网+后台系统|前后分离VUE
  19. ak和sk的意思及用法
  20. Rust中的channel

热门文章

  1. 北京“新城卓越”黑中介租房感受
  2. 地理计算 | 计算两个坐标点射线的交点(前方交会)
  3. php关联规则,如何理解关联规则apriori算法
  4. 什么是企业防火墙,什么是策略?
  5. UOS与Deepin OS区别详解
  6. 随心所欲Do whatever you want——Minecraft
  7. Docker 详细教程
  8. 0基础软件测试小白,如何找到一份高薪的工作?
  9. 【人脸识别】人数统计【含GUI Matlab源码 2121期】
  10. 浅谈在实验室的一个作品---8x8x8光立方