简单的HTTP服务器程序的编写

news/2024/7/3 7:08:13

HTTP 协议一般指 HTTP(超文本传输协议)。

超文本传输协议(英语:HyperText Transfer Protocol,缩写:HTTP)是一种用于分布式、协作式和超媒体信息系统的应用层协议,是因特网上应用最为广泛的一种网络传输协议,所有的万维网文件都必须遵守这个标准。

HTTP是一个基于TCP/IP通信协议来传递数据(我们要传输的数据是HTTP报文,报文是通过TCP协议来传输的)

下面来看这么一个题,当你在浏览器输入www.baidu.com,按下回车之后会发生哪些事情?

 当你在浏览器输入www.baidu.com百度的域名之后,先由DNS查询到百度服务器的某一IP,然后由浏览器与服务器三次握手建立连接,然后浏览器发送HTTP请求报文,服务器回复HTTP应答报文(应用层是HTTP协议,但是传输层还是调用的TCP协议)

下面来看一下关于HTTP的一些方法和HTTP状态码和状态信息及含义:-------截图取自《Linux高性能服务器编程》

 我们在前面的那个图里面写到了HTTP的请求报文和HTTP的应答报文,那么这个HTTP报文是啥呢?

HTTP请求报文:

 HTTP应答报文:有个东西得说明一下 无论是应答报文还是请求报文最后都有个\r\n (最后的空行中也有一个\r\n)

这些HTTP报文的格式得我们自己去组装这玩意,相当于我们在TCP那个中的send,recv之后发出的ok那玩意,区别就是TCP中我们不需要自己去组装这格式 

那么HTTP报文中那些东西究竟什么意思呢?这玩意解释起来贼麻烦,都在《Linux高性能服务器编程》中,我将这本书的pdf格式的电子书放在下面的链接中了

链接:https://pan.baidu.com/s/19x4ZB9wCNenq0YU5IBX72w 
提取码:1234

下面来编写一个简单的HTTP服务器:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>int socket_init();int main()
{int sockfd = socket_init();assert(sockfd != -1);while(1){struct sockaddr_in caddr;int len = sizeof(caddr);int c = accept(sockfd,(struct sockaddr*)&caddr,&len);if(c < 0){continue;}char buff[1024] = {0};int n = recv(c,buff,1023,0); //接收浏览器发来的数据if(n == 0)  //n == 0 的话 就是客户端关闭了{close(c);continue;}printf("recv = %s \n",buff);send(c,"helo HTTP",9);close(c);}
}int socket_init()
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);//创建套接字  SOCK_DGRAM这个为UDP数据报套接字assert(sockfd != -1);struct sockaddr_in saddr; memset(&saddr,0,sizeof(saddr));saddr.sin_family = AF_INET;saddr.sin_port = htons(80); //HTTP默认端口为80号端口saddr.sin_addr.s_addr = inet_addr("192.168.0.115");int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));if(res == -1){return -1;}if(listen(sockfd,5) == -1){return -1;}return sockfd;
}

在上面的第50行代码中的IP绑定中,使用的是192.168.0.115这个真实IP(也可以使用127.0.0.1这个本机IP,查看本机IP(Linux中是ifconfig,Windows中是ipconfig)),要是使用了本机IP的话,只能本机访问,例如在虚拟机中的火狐浏览器访问,而本身的Windows就不能访问这个服务器,使用真实IP的话,Windows和Ubuntu中都可以访问:

当我们一切准备就绪准备运行这个服务器的时候: 

发现sockfd = -1 ,查看代码发现使用的端口号是80,端口号5000以内的都是管理员才有权限使用的端口,所以我们切换一下管理员权限:

sudo su

然后就可以让服务器跑起来了,然后我们在Ubuntu和Windows中都对它进行以下访问:

 上图我们在服务器中写的hello HTTP 的内容显示到了屏幕上

上图就是在运行服务器之后,被别人访问之后我们后台看到的东西,可以看出来实在Ubuntu加二Windows上面访问的,浏览器分别为chorm浏览器和火狐(Firefox)浏览器,而在下方那个.ico的东西是小图标,而我们为什么没有出现上方图片中的HTTP请求报文和HTTP的应答报文的呢?那玩意那个报文得自己去组装,这里说一下思路,获取我们在访问的时候的文件名字,来判断浏览器想要服务器的什么文件,还有那个应答报文中的content-length这个就是获取报文的大小,会用到lseek这个函数,将大小返回.这样就基本将应答报文组装完成了!

关于HTTP的知识点就记住HTTP是个应用层的东西,它的底层还是靠TCP来实现,然后就是在上面写的那道题,很经典,最后的东西就是关于HTTP请求方法和HTTP状态码和状态信息的熟记!

"共同学习,共同进步!"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pgtn.cn/news/15596.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

【C++】何时需要自定义拷贝构造函数和赋值符

先来说结论&#xff1a;当类中有指针类型成员变量的时候&#xff0c;一定要自定义拷贝构造和赋值运算符 原因&#xff1a;当我们在有指针类成员变量的时候&#xff0c;还是用默认拷贝构造函数(拷贝构造函数执行的时候会调用赋值符)&#xff0c;默认赋值为浅拷贝&#xff0c;会…

iOS自动布局一

Align: Pin&#xff1a; 转载于:https://www.cnblogs.com/123qw/p/4404167.html

【C++】左值、右值、移动拷贝构造函数、移动赋值函数

左值和右值的定义以及区别: 先来看在C语言中的左值和右值 &#xff1a; 左值&#xff1a;可赋值的值为左值 右值&#xff1a;不可赋值的值为右值 再来看C中左值右值的定义如下&#xff1a; 左值&#xff1a;可以取地址的值&#xff08;有名字的值、非临时量&#xff09; …

【C++】typedfe和宏定义的区别

先来说结论&#xff1a; 1.宏定义作用于编译之前(也就是预编译阶段&#xff0c;而typedef作用于编译阶段 2.typedef仅限于类型的重定义&#xff0c;而宏定义不仅可以为类型起别名还可以为数值定义起别名(简单的替换) 下面来看一下区别 下面这是typedef的用法 typedef int* PI…

GPS部标平台的架构设计(十)-基于Asp.NET MVC构建GPS部标平台

在当前很多的GPS平台当中&#xff0c;有很多是基于asp.NETsiverlight开发的遗留项目&#xff0c;代码混乱而又难以维护&#xff0c;各种耦合和关联&#xff0c;要命的是界面也没见到比Javascript做的控件有多好看&#xff0c;随着需求的增多&#xff0c;平台已经臃肿不堪。 设计…

【C++】虚函数

虚函数是构成C多态的重要一步&#xff0c;今天来说一下虚函数&#xff01; 虚函数&#xff1a; 在基类(或父类)中&#xff0c;使用virtual关键字对函数进行声明为并在一个或多个派生类(子类)中被重新定义的成员函数&#xff0c;通过指向派生类的基类指针或引用&#xff0c;访…

看了极光推送技术原理的几点思考

看了极光推送技术原理的几点思考 分类&#xff1a; android2012-11-26 20:50 16586人阅读 评论(18) 收藏 举报目录(?)[] 移动互联网应用现状 因为手机平台本身、电量、网络流量的限制&#xff0c;移动互联网应用在设计上跟传统 PC 上的应用很大不一样&#xff0c;需要根据手机…

【C++】多态(早期绑定、后期绑定)、抽象类(纯虚函数)、虚析构函数

我们都知道面向对象编程的三大特征是封装、继承、多态&#xff0c;今天我们就来说一下其中之一的多态。 概念&#xff1a; 多态&#xff1a; 多态字面意思就是多种形态&#xff0c;C 多态意味着调用成员函数时&#xff0c;会根据调用函数的对象的类型来执行不同的函数。(取自…