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

linux学习笔记(33)网络编程——HTTP协议

HTTP 超文本传输协议

它到传输层只用tcp

浏览器与服务器通信过程

浏览器与 web 服务器在应用层通信使用的是 HTTP 协议(超文本传输协议),而 HTTP协议在传输层使用的是 TCP 协议。那么浏览器需要和 web 服务器三次握手建立连接后,才
可以发送 HTTP 请求报文,服务器收到请求报文后,向浏览器回复 HTTP 应答报文。
浏览器向服务器发起连接前,需要得到服务器的 IP 及端口。用户在浏览器中通常只输入网址(网站域名),浏览器会通过 DNS 服务查询获取到服务器的 IP 地址。对于端口来讲,
使用 HTTP 协议的程序一般默认使用 80 端口。
浏览器服务器建立连接后,如果两次以上的请求复用同一个 TCP 连接,则称之为长连接。
如果浏览器发送一次请求报文,服务器回复一次应答就断开连接,下次交互再重新进行三次握手建立连接,那么就被称作短连接。
使用长连接显然是更好一些,可以减少网络中的同步报文,也使得服务器的响应速度变快。
常见的 web 服务器有:
◼ Apache: 简单、速度快、性能稳定,并可做代理服务器使用
◼ IIS(Internet Information Server):安全性、强大、灵活
◼ Nginx:小巧而高效,可以做高效的负载均衡反向代理
◼ Tomcat:技术先进、性能稳定、免费

HTTP方法(常用的)

GET - 获取资源:

GET /users/123 HTTP/1.1
Host: api.example.com

像说: "给我用户123的信息"

POST - 创建资源:

POST /users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 45{"name":"张三","email":"zhang@example.com"}

像说: "创建一个新用户,这是用户信息"

PUT - 更新资源:

PUT /users/123 HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 47{"name":"李四","email":"li@example.com"}

像说: "把用户123的信息更新成这个"

DELETE - 删除资源:

DELETE /users/123 HTTP/1.1
Host: api.example.com

像说: "删除用户123"

HTTP状态码

常见状态码:

// 2xx 成功
200 OK          // 请求成功
201 Created     // 创建成功// 3xx 重定向  
301 Moved Permanently  // 永久重定向
302 Found             // 临时重定向// 4xx 客户端错误
400 Bad Request       // 请求格式错误
401 Unauthorized      // 未认证
403 Forbidden         // 禁止访问
404 Not Found         // 找不到页面// 5xx 服务器错误
500 Internal Server Error  // 服务器内部错误
502 Bad Gateway           // 网关错误

HTTP头部字段

常用请求头:

GET / HTTP/1.1
Host: www.example.com          // 目标域名
User-Agent: Mozilla/5.0        // 浏览器信息
Accept: text/html              // 可接受的类型
Accept-Language: zh-CN         // 语言偏好
Cookie: session=abc123         // Cookie数据

常用响应头:

HTTP/1.1 200 OK
Content-Type: text/html        // 内容类型
Content-Length: 1024           // 内容长度
Set-Cookie: session=xyz789     // 设置Cookie
Cache-Control: max-age=3600    // 缓存控制

我来给你写一个最简单的HTTP服务器,就叫myhttp

1. 最简版的myhttp

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>#define PORT 8080
#define BUFFER_SIZE 4096// 发送HTTP响应
void send_response(int client_fd, const char* content) {char response[BUFFER_SIZE];snprintf(response, sizeof(response),"HTTP/1.1 200 OK\r\n""Content-Type: text/html\r\n""Content-Length: %zu\r\n""Connection: close\r\n""\r\n""%s", strlen(content), content);write(client_fd, response, strlen(response));
}int main() {printf("🚀 MyHTTP 服务器启动!\n");printf("📡 访问: http://localhost:%d\n", PORT);// 创建TCP socketint server_fd = socket(AF_INET, SOCK_STREAM, 0);// 设置端口重用int opt = 1;setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));// 绑定地址struct sockaddr_in address;address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);bind(server_fd, (struct sockaddr*)&address, sizeof(address));listen(server_fd, 5);printf("✅ 服务器准备就绪,等待连接...\n\n");while (1) {// 接受客户端连接int client_fd = accept(server_fd, NULL, NULL);char buffer[BUFFER_SIZE];int bytes_read = read(client_fd, buffer, sizeof(buffer) - 1);if (bytes_read > 0) {buffer[bytes_read] = '\0';// 打印请求信息(前200字符)printf("📨 收到请求:\n%.200s\n", buffer);// 简单的路由处理if (strstr(buffer, "GET /hello ")) {char* html = "<html>""<body style='font-family: Arial; padding: 20px;'>""<h1>👋 你好!</h1>""<p>这是我的MyHTTP服务器!</p>""<p><a href='/time'>查看时间</a></p>""<p><a href='/about'>关于</a></p>""</body>""</html>";send_response(client_fd, html);}else if (strstr(buffer, "GET /time ")) {char* html = "<html>""<body style='font-family: Arial; padding: 20px;'>""<h1>⏰ 当前时间</h1>""<p>2024年1月1日 12:00:00</p>""<p><a href='/hello'>返回首页</a></p>""</body>""</html>";send_response(client_fd, html);}else if (strstr(buffer, "GET /about ")) {char* html = "<html>""<body style='font-family: Arial; padding: 20px;'>""<h1>ℹ️ 关于MyHTTP</h1>""<p>这是一个用C语言编写的简单HTTP服务器</p>""<p>支持多页面浏览!</p>""<p><a href='/hello'>返回首页</a></p>""</body>""</html>";send_response(client_fd, html);}else {// 默认页面char* html = "<html>""<body style='font-family: Arial; padding: 20px;'>""<h1>🌐 MyHTTP 服务器</h1>""<p>欢迎使用我的HTTP服务器!</p>""<ul>""<li><a href='/hello'>欢迎页面</a></li>""<li><a href='/time'>时间页面</a></li>""<li><a href='/about'>关于页面</a></li>""</ul>""</body>""</html>";send_response(client_fd, html);}}close(client_fd);}close(server_fd);return 0;
}

2. 编译和运行

编译:

gcc -o myhttp myhttp.c

运行:

./myhttp

3. 测试你的MyHTTP服务器

方法1:用浏览器访问

打开浏览器,访问这些网址:
http://localhost:8080
http://localhost:8080/hello
http://localhost:8080/time  
http://localhost:8080/about

方法2:用curl命令测试

curl http://localhost:8080
curl http://localhost:8080/hello
curl http://localhost:8080/time

4. 增强版:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 8080
#define BUFFER_SIZE 1024
// 发送HTML页面
void send_html(int client_fd, char* title, char* content) {char response[BUFFER_SIZE];snprintf(response, sizeof(response),"HTTP/1.1 200 OK\r\n""Content-Type: text/html\r\n""\r\n"  // 空行分隔头部和内容"<html><body><h1>%s</h1><p>%s</p></body></html>",title, content);write(client_fd, response, strlen(response));
}// 发送404错误页面
void send_404(int client_fd) {char* response ="HTTP/1.1 404 Not Found\r\n""Content-Type: text/html\r\n""\r\n""<html><body><h1>404 页面未找到</h1></body></html>";write(client_fd, response, strlen(response));
}int main() {printf("🚀 HTTP服务器启动: http://localhost:%d\n", PORT);// 1. 创建socketint server_fd = socket(AF_INET, SOCK_STREAM, 0);// 2. 设置地址和端口struct sockaddr_in address = {.sin_family = AF_INET,.sin_addr.s_addr = INADDR_ANY,  // 监听所有网卡.sin_port = htons(PORT)         // 端口号};// 3. 绑定端口bind(server_fd, (struct sockaddr*)&address, sizeof(address));// 4. 开始监听listen(server_fd, 5);printf("✅ 服务器准备就绪!\n\n");// 主循环:处理客户端请求while (1) {// 5. 接受客户端连接int client_fd = accept(server_fd, NULL, NULL);char buffer[BUFFER_SIZE];int bytes = read(client_fd, buffer, sizeof(buffer) - 1);if (bytes > 0) {buffer[bytes] = '\0';// 6. 根据请求路径返回不同内容if (strstr(buffer, "GET / ")) {send_html(client_fd, "首页", "欢迎访问我的网站!");}else if (strstr(buffer, "GET /hello ")) {send_html(client_fd, "Hello页面", "你好!这是一个示例页面。");}else if (strstr(buffer, "GET /about ")) {send_html(client_fd, "关于", "这是一个简单的HTTP服务器");}else {send_404(client_fd);  // 其他路径返回404}}// 7. 关闭连接close(client_fd);}close(server_fd);return 0;
}

5. 创建测试HTML文件

创建一个index.html文件来测试文件服务功能:
<!DOCTYPE html>
<html>
<head><title>MyHTTP 服务器</title><style>body { font-family: Arial; padding: 40px; background: #f0f0f0; }.container { max-width: 800px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; }h1 { color: #333; }a { color: #007bff; text-decoration: none; }a:hover { text-decoration: underline; }</style>
</head>
<body><div class="container"><h1>🎉 欢迎使用 MyHTTP!</h1><p>这是一个用C语言编写的HTTP服务器</p><h2>📚 可用页面:</h2><ul><li><a href="/hello">Hello 页面</a></li><li><a href="/time">时间页面</a></li><li><a href="/about">关于页面</a></li></ul><h2>⚡ 特性:</h2><ul><li>支持HTTP/1.1协议</li><li>多页面路由</li><li>静态文件服务</li><li>错误处理</li></ul></div>
</body>
</html>

6. 项目结构

myhttp/
├── myhttp.c      # 主程序
├── index.html    # 主页文件
└── README.md     # 说明文档

你的MyHTTP服务器现在可以:

  1. ✅ 处理HTTP请求
  2. ✅ 支持多个页面路由
  3. ✅ 返回HTML内容
  4. ✅ 处理404错误
  5. ✅ 服务静态文件
现在你有一个真正可用的HTTP服务器了!可以继续添加更多功能,比如POST处理、JSON API、文件上传等。🚀
http://www.dtcms.com/a/487856.html

相关文章:

  • 守护线程,礼让线程,插入线程
  • 网站建设好不好北京数据优化公司
  • 网站建设服务非常好湖南岚鸿公司万网怎样安装wordpress
  • FPGA职位经典笔/面试题(附答案与解析)
  • 哪个网站百度收录快怎样免费安装wordpress
  • 给客户做网站建设方案推广计划地域设置的作用描述不正确的是
  • N8N 系列:入门级,告别 SQL “天书”!N8N原生数据表 Data Tables,让新手也能轻松管理数据,上手即会用
  • 整体设计 逻辑系统程序 之28 拼语言+ CNN 框架核心定位、三阶段程序与三种交换模式配套的方案讨论 之1
  • 谷歌自建站和优化中国对外贸易公司排名
  • 网站被百度k掉怎么办手机网站制作方案
  • 永磁同步电机无速度算法--基于降阶准谐振ESO和Newton-Raphson方法PLL的PMSM无速度传感器控制
  • 网站建设推广方案策划书羽毛球赛事直播app
  • 做摄影网站的目的是什么给自己的网站做代言
  • GEO实战之GEO 在营销生态中的定位:GEO 与其他营销渠道的协同效应
  • wordpress怎么做响应式网站phpcms v9漏洞
  • 做网站的每天打电话咋办wordpress轻语博客
  • 邯郸网站建设费用做网站费用 优帮云
  • 网站建设职责要求网站开发命名规则
  • 2015年下半年试题三:论面向服务的架构及其应用
  • 接私活做网站设计丰台网站建设推广seo
  • 阿里云国际代理商:有哪些文件适合阿里云CDN分发?
  • 轻淘客网站模板网络营销八大工具
  • 如何建立一个网站根目录织梦个人博客网站源码
  • 爬动的蠕虫
  • 关于网站开发的一些论文公司注册要多少费用
  • 做网站用什么技术推广代理平台登录
  • 破解宠物走失难题:智能防丢器守护你的爱宠
  • B3968 [GESP202403 五级] 成绩排序
  • 安徽建设工程信息网站珠海网站优化公司
  • 做ps的网站有哪些功能吗深圳一百讯网站建设