INADDR_ANY
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(Port);
seraddr.sin_addr.s_addr = INADDR_ANY; //INADDR_ANY 表示监听所有IP地址
ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
ret = listen(sockfd, 10);
INADDR_ANY表示监听所有发往本机IP的请求
固定IP只监听发往这一个IP的请求
如果本机有多个IP,固定IP可以起到隔离的作用
如果本机只有一个IP,二者并没有什么不同
strtok();
将字符串拆分成多个子串(token)
第一次调用传入要拆分的字符串
后续调用传入 NULL 继续拆分
会修改原字符串(将分隔符替换为 \0)
不是线程安全的(多线程用 strtok_r())
参数:
str 第一次调用:要拆分的字符串
后续调用:NULL(继续拆分)
delim 分隔符集合(包含一个或多个字符)
返回值:
成功拆分 指向子串的指针
没有更多子串 NULL
char *token;
token = strtok(str, ",");
while (token != NULL) {
printf(" %s\n", token);
// 后续调用:传入 NULL
token = strtok(NULL, ",");
}
也就是按照输入的分隔符号,将字符串分隔符全变为\0,(如果一直分割到strtok返回NULL),然后返回的是每个分割好字符串的首个字母的指针
===============================================================================================
服务器收到 GET 请求后, 服务器返回的内容必须遵循 HTTP 响应格式,分为三大部分:
-
状态行
-
响应头
-
空行
-
响应体
例子:
HTTP/1.1 200 OK\r\n 状态行
Server: TinyServer\r\n 服务器头
Content-Type: text/html; charset=utf-8\r\n 内容类型头
Content-Length: 135\r\n 内容长度头,单位是字节,这里表示响应体的大小是 135 字节
Connection: keep-alive\r\n 连接头,保持连接,客户端可以继续发送请求
-----------------以上为响应头部分---------------------
\r\n 空行 以\r\n结尾, 分割响应头和响应体 (必须有)
<html>
<head><title>我的网页</title></head>
<body>
<h1>欢迎访问我的服务器!</h1> 响应体
<p>这是一个测试页面。</p>
</body>
</html>
Content-Type:决定了浏览器怎么显示内容
text/html → 渲染为网页
text/plain → 显示为纯文本
application/json → JSON 数据
image/jpeg → 显示图片
Content-Length:告诉浏览器响应体有多少字节(必须准确,否则浏览器会卡住或乱码)
响应体(Response Body) 就是服务器返回给客户端的实际数据内容。
除去GET 请求,其他请求方法(POST、PUT、DELETE等)的处理方式基本相同。
GET 请求:用于获取资源,请求头(Request Header)中不包含 Content-Type:,请求体(Request Body)为空。
POST 请求:将数据提交到服务器处理,请求头(Request Header)中包含 Content-Type:,请求体(Request Body)中包含要提交的数据。
PUT 请求:更新服务器上的资源,请求头(Request Header)中包含 Content-Type:,请求体(Request Body)中包含要更新的数据。
DELETE 请求:删除服务器上的资源,请求头(Request Header)中包含 Content-Type:,请求体(Request Body)中包含要删除的资源的路径。
=================================================================================
│ │ │ │
协议 IP地址 端口 路径
本地回环地址,127.0.0.1 表示本机IP地址
=================================================================================
strstr;
#include <string.h>
char *strstr(const char *str, const char *substr);
功能:在字符串str中查找子字符串substr,返回子字符串的起始位置指针
参数:
str :要查找的字符串
substr:要查找的子字符串
返回值:
成功:指向子字符串的起始位置指针
失败:NULL
例子:
char *str = "hello world";
char *substr = "world";
char *p = strstr(str, substr);
if (p != NULL)
{
printf("子字符串 %s 存在于字符串 %s 中,起始位置为:%p\n", substr, str, p);
}
else
{
printf("子字符串 %s 不存在于字符串 %s 中\n", substr, str);
}
结果:
子字符串 world 存在于字符串 hello world 中,起始位置为:0x7f800000000000000
===============================================================================
sscanf;
#include <stdio.h>
int sscanf(const char *str, const char *format, ...);
功能:将字符串str中的格式化数据解析为指定的变量
参数:
str :要解析的字符串
format:格式化字符串,包含占位符(%)
返回值:
成功:成功解析的变量数量
失败:-1
%15s 表示解析15个字符,直到遇到空格或换行符
%255s 表示解析255个字符,直到遇到空格或换行符
例子:
char line1024 = "GET / HTTP/1.1\r\n";
char method16 = {0};
char url256 = {0};
sscanf(line, "%15s %255s", method, url);
printf("请求方法:%s\n", method);
printf("请求URL:%s\n", url);
结果:
请求方法:GET
请求URL:/
=====================================================================================
strtok_r;
#include <string.h>
char *strtok_r(char *str, const char *delim, char **saveptr);
功能:将字符串str根据分隔符delim拆分成多个子串
参数:
str :第一次调用:要拆分的字符串
后续调用:NULL(继续拆分)
delim :分隔符集合(包含一个或多个字符)
saveptr:指向上一次拆分位置的指针,用于存储下一次拆分的位置
返回值:
成功拆分 指向子串的指针
没有更多子串 NULL
与strtok的区别:
-
strtok_r是线程安全的,而strtok不是
-
strtok_r返回的指针是字符串的起始位置,而strtok返回的指针是字符串的结束位置
多线程中strtok_r每调用一次都需要提供一个save指针,所以互不干扰,strtok只有一个指针,所以抢着用?
=====================================================================================
atoi;
#include <stdlib.h>
int atoi(const char *str);
功能:将字符串str转换为整数
参数:
str :要转换的字符串
返回值:
成功:转换后的整数
失败:-1
例子:
char *str = "123";
int num = atoi(str);
printf("转换后的整数:%d\n", num);
结果:
转换后的整数:123
=====================================================================================
memcpy;
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
功能:将内存区域src中的n个字节复制到内存区域dest中
参数:
dest :目标内存区域
src :源内存区域
n :要复制的字节数
返回值:
成功:dest
失败:NULL
=====================================================================================
strchr;
#include <string.h>
char *strchr(const char *str, int c);
功能:在字符串str中查找字符c,返回字符c的起始位置指针
参数:
str :要查找的字符串
c :要查找的字符
返回值:
成功:指向字符c的起始位置指针
失败:NULL
例子:
char *str = "hello world";
char *p = strchr(str, 'w');
if (p != NULL)
{
printf("字符 w 存在于字符串 %s 中,起始位置为:%p\n", str, p);
}
else
{
printf("字符 w 不存在于字符串 %s 中\n", str);
}
结果:
字符 w 存在于字符串 hello world 中,起始位置为:0x7f800000000000000
两者的核心区别在于:strchr() 找的是单个字符,strstr() 找的是子字符串。
================================================================================
商品搜索跳转页面
还需要一个商品展示页面,用户通过搜索进入该页面,页面可滑动,每个商品卡片从上到下的详细信息为,商品图片,两行文字,第一行商品简洁的前12个字,最后一行从左到右商品价格,一个查看详情。点击查看详情后,即可跳转到商品的详细页面,这个之后再说。同时该搜索跳转页面依然要保留搜索框,在最上面,商品卡片排版为,每行两个,不限制行数,商品选择逻辑以及摆放顺序逻辑为匹配搜索内容与所有商品名字以及简洁,相同字符越多商品越靠前
商品数据信息保存
商品数据信息保存在数据库中,数据库表结构如下:
商品ID 商品名称 商品简介 商品价格 商品图片 商品状态
图片库
image
|商品ID
|商品ID
|商品ID
|1
|2
|3