协议是一种 "约定". socket api的接口, 在读写数据时, 都是按 "字符串" 的方式来发送接收的. 如果我们要传输一些"结构化的数据" 怎么办呢?
request
response
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include"Protocol.hpp"
using func_t=std::function;
enum{
USAGE_ERR=1,
SOCKET_ERR,
BIND_ERR,
LISTEN_ERR
};
static const uint16_t gport=8080;
static const int gbacklog=5;
class HttpServer{
public:
HttpServer(func_t func,const uint16_t &port=gport):_func(func),_listensock(-1),_port(port){}
void initServer(){
//1.创建套接字
_listensock=socket(AF_INET,SOCK_STREAM,0);
if(_listensock<0){
exit(SOCKET_ERR);
}
//2.bind绑定自己的网络信息
struct sockaddr_in local;
memset(&local,0,sizeof(local));
local.sin_family=AF_INET;
local.sin_port=htons(_port);
local.sin_addr.s_addr=INADDR_ANY;
if(bind(_listensock,(struct sockaddr*)&local,sizeof(local))<0){
exit(BIND_ERR);
}
//3.设置socket为监听状态
if(listen(_listensock,gbacklog)<0){
exit(LISTEN_ERR);
}
}
void HandlerHttp(int sock){
std::cout << "处理HTTP请求。" << std::endl;
char buffer[4096];
HttpRequest req;
HttpResponse resp;
ssize_t n = recv(sock, buffer, sizeof(buffer)-1, 0);
if(n > 0){
buffer[n] = '\0'; // 确保字符串以空字符结尾
std::cout << "接收到的请求内容: " << buffer << std::endl;
req.inbuffer = buffer;
if(_func(req, resp)) { // 如果处理成功
std::cout << "发送的响应内容: " << resp.outbuffer << std::endl;
ssize_t send_result = send(sock, resp.outbuffer.c_str(), resp.outbuffer.size(), 0);
if(send_result < 0) {
std::cerr << "发送失败,错误: " << strerror(errno) << std::endl;
}
} else {
std::cerr << "处理函数未能成功处理请求。" << std::endl;
}
} else if(n == 0) {
std::cerr << "客户端关闭了连接。" << std::endl;
} else {
std::cerr << "接收失败,错误: " << strerror(errno) << std::endl;
}
close(sock);
std::cout.flush();
std::cerr.flush();
}
void start(){
for(;;){
//4.server获取新链接
struct sockaddr_in peer;
socklen_t len=sizeof(peer);
int sock=accept(_listensock,(struct sockaddr*)&peer,&len);
if(sock<0){
continue;
}
// version 2 多进程版(2)
pid_t id = fork();
if (id == 0) // child
{
close(_listensock);
if(fork()>0)
exit(0);
HandlerHttp(sock);
close(sock);
std::cout.flush();
std::cerr.flush();
exit(0);
}
close(sock);
// father
waitpid(id, nullptr, 0);
}
}
private:
int _listensock;
uint16_t _port;
func_t _func;
};
#pragma once
#include
#include
#include
class HttpRequest{
public:
std::string inbuffer;
std::string reqline; //请求行
std::vector reqheader; //请求报头
std::string body; //正文
std::string method;
std::string url;
std::string httpversion;
std::string path;
};
class HttpResponse{
public:
std::string outbuffer;
};
#include"HttpServer.hpp"
#include"Protocol.hpp"
#include
using namespace std;
void Usage(std::string proc){
cerr<<"Usage:\n\t"<for test hello world
北京交通广播《一路畅通》“交通大家谈”节目,特邀北京市交通委员会地面公交运营管理处处长赵震、北京市公安局公安交通管理局秩序处副处长 林志勇、北京交通发展研究院交通规划所所长 刘雪杰为您解答公交车专用道6月1日起社会车辆进出公交车道须注意哪些?