1. 简易HTTP服务器
实现一个最简单的HTTP服务器, 网页上输出 “hello world”;
#pragma once
#include <iostream>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<signal.h>
#define BACKLOG 5
using namespace std;
class httpServer{
private:
int port;
int lsock;
public:
httpServer(int _p):port(_p),lsock(-1)
{}
void InitServer()
{
signal(SIGCHLD,SIG_IGN);
lsock = socket(AF_INET, SOCK_STREAM, 0);
if( lsock < 0 )
{
cerr << "socket error " << endl;
exit(2);
}
struct sockaddr_in local;
local.sin_family = AF_INET;
local.sin_port = htons(port);
local.sin_addr.s_addr = INADDR_ANY;
if(bind(lsock, (struct sockaddr*)&local, sizeof(local)) < 0){
cerr << "bind error!" << endl;
exit(3);
}
if(listen(lsock, BACKLOG) < 0){
cerr << "listen error"<<endl;
exit(4);
}
}
void Echo_http(int sock)
{
char request[2048];
ssize_t s = recv(sock,request,sizeof(request),0);//bug
if(s > 0){
//表示接收成功
request[s] = 0;
cout << request << endl;
string response = "HTTP/1.0 200 OK\r\n";//响应行
response += "Content-type: text/html\r\n";//响应报头(Content-type:这里是有一个空格的)
response += "\r\n";//空行
response += "\
<!DOCTYPE html>\
<html>\
<head>\
<title>192.168.31.223</title>\
</head>\
<body>\
<h1>Welcome</h1>\
<p>helloworld</p>\
</body>\
</html>\
";
//响应正文
send(sock,response.c_str(),response.size(),0);
}
close(sock);
}
void start()
{
struct sockaddr_in peer;
for(;;){
socklen_t len = sizeof(peer);
int sock = accept(lsock, (struct sockaddr*)&peer,&len);
if( sock < 0 ){
cerr << "accept error!" << endl;
continue;
}
if(fork() == 0){
close(lsock);
Echo_http(sock);
exit(0);
}
close(sock);
}
}
~httpServer()
{
close(lsock);
}
};
通过telnet进行远程连接尝试
因为即使你输入的是192.168.31.223的ip地址,但是你拷贝下来之后,就会发现变为http://192.168.31.223/,所以阅览器是知道你所使用的通讯协议的,但是http默认的绑定的端口号是80,所以还需要自己在进行手动的修改port。
2. http和https
HTTP端口号:80
HTTPS端口号:443
https相较于http协议,最主要的就是进行了数据的加密。
https所采用的加密是对称加密算法。但是会发现,在第一次进行通信的时候,如果直接把对称秘钥进行传送,那么这个加密过程就形同虚设。所以他们要进行密钥协商过程。
2.1 秘钥协商过程
秘钥协商过程是由SSL/TLS层进行的,但是是由https进行触发的。
完整过程:
server发送公钥,client端接收到公钥以后对数据和对称秘钥进行加密,然后在发送给server端,server端拿着独有的非对称加密的私钥进行解密,然后获得对称秘钥,以后他们之间的通信将使用对称秘钥进行加密。
那么为什么这么麻烦呢?为什么不直接使用非对称加密算法进行通信呢?
是因为非对称加密的效率低,然而对称加密算法效率高。
2.2 数据摘要和数据签名
解决中间信息被篡改问题。
如何保证所发过来的信息是没有被修改过的呢?需要使用到数据摘要和数据签名技术。
- 将你所发的数据可以通过HASH算法得到一个定长的字符序列(数据摘要),然后和你的数据赋在一起进行传送过去,接收方在拿到数据之后也通过HASH算法得到一个定长的序列,和你发过来的进行对比。
但是这其中有一个问题,难道黑客就不能把修改过后的内容,也是用你的HASH算法得到一个数据摘要赋在里面在发送过来吗?答案是可以的,所以这是完全不够的。
- 原始数据在生成数据摘要之后在进行秘钥加密,就会得到一个加密的数据摘要,它也叫做数据签名或者指纹(对于黑客来说,他是拿不到这个秘钥的,所以即使它能够拿到你的数据,但是却无法对数据签名进行修改,当接收端拿到以后可以通过数据摘要进行对比,就会发现,数据有被篡改过的问题。)
2.3 证书
解决对远端服务器进行身份认证的问题。
即使中间人无法修改数据了,但是他依旧可以看到所发的数据,这个本身来说也是一种信息泄露。(这里还需要继续补充)
windows+R输入certmgr.msc,可以看到本机相关的证书信息。