-
背景描述
该系统为创建网络并发服务器,搭建HTML网络页面框架,通过HTTP超文本网络传输与用户建立连接(TCP建立连接),从自己建立的数据库中查询用户所需信息,使用户能在网页中直接查询相关内容。本系统包括4个页面,包括(一级登陆页面,二级商品查询信息页面,三级商品概述页面,四级商品详情页面),使用户可以精准查询。
-
项目框架
2.1主要功能框图
2.2系统结构框图
- 数据库查询
- 模块介绍
网页界面:分为四级网页界面:分别是登录页面,查询页面,商品页面,商品详情页面
登录页面:输入账号和密码
查询页面:输入待查询的商品名称
商品页面:展示所有匹配到的商品
商品详情页面:展示用户所有商品的详细信息,包括参数,价格等
-
详细设计文档
3.1数据输入与显示
流程图:(附录)
3.2网络模块
接口说明:
接口选项 | 参数说明 | 返回值 | 接口描述 |
1.init_tcp | 本机作为服务器的ip以及用http协议创建连接的端口号。 | 待绑定的套接字 | 初始化 TCP 连接 ,这个函数正确地设置了 socket 选项,绑定了 IP 地址和端口,并开始监听连接。 |
2recv_http_request | 已经accept后的套接字connfd,接收到的http请求,请求的大小。 | 接收到的请求报文的大小 | 接收 HTTP 请求 ,这个函数从客户端读取 HTTP 请求。 |
3.parse_http_req | 接收到的http请求。 | 无 | 解析 HTTP 请求 ,这个函数使用 strtok 来解析请求方法、URL 和内容 |
4.Callback/callback2 | callback函数的固定参数 | 无 | 处理从 SQLite 查询返回的数据 |
5find_pictures | connfd,拼接好的一部分报文,需要在数据库查找的数据名 | 无 | SQLite 数据库中查询数据,并使用回调函数发送响应 |
6.find_detail | connfd,拼接好的一部分报文,需要在数据库查找的数据名 | SQLite 数据库中查询数据,并使用回调函数发送响应 | |
7.send_http_head 和 send_http_file | connfd | 用于构建和发送 HTTP 响应 | |
8.send_http_response | connfd | 根据请求的 URL 和方法来决定发送什么内容 |
实现代码:
主要部分:
#include<stdio.h>
#include <sqlite3.h>
#include "net.h"
int lead;
int recv_http_request(int connfd,char *http_req,int maxlen);
int parse_http_req(char *http_req,HTTP_REQ_text *phttp);
int callback(void *arg,int column_cnt,char **column_value,char **column_name);
int find_images(int connfd,char file[1024]);
int send_http_head(int connfd);
int send_http_file(int connfd,char *filename);
int send_http_response(int connfd,HTTP_REQ_text *phttp);
char name_buf[512] = {0};
int init_tcp(const char *ip, unsigned short port)
{
int option,optlen;
int socfd = socket(AF_INET,SOCK_STREAM,0);
if(socfd < 0)
{
perror("fail socket");
return -1;
}
optlen = sizeof(option);
option = 1;
setsockopt(socfd,SOL_SOCKET,SO_REUSEADDR,(void *)&option,optlen);
struct sockaddr_in ser;
ser.sin_family = AF_INET;
ser.sin_port = htons(port);
ser.sin_addr.s_addr = inet_addr(ip);
int ret = bind(socfd,(struct sockaddr *)&ser,sizeof(ser));
if(-1 == ret)
{
perror("fail bind");
return -1;
}
ret = listen(socfd,128);
if(-1 == ret)
{
perror("fail listen");
return 0;
}
return socfd;
}
int recv_http_request(int connfd,char *http_req,int maxlen)
{
lead = connfd;
memset(http_req,0,maxlen);
ssize_t size = read(connfd,http_req,maxlen);
if(size <= 0)
{
perror("read error");
return 0;
}
printf("------------http_req-----------\n");
printf("%s\n",http_req);
printf("-------------------------------\n");
return size;
}
int parse_http_req(char *http_req,HTTP_REQ_text *phttp)
{
memset(phttp,0,sizeof(HTTP_REQ_text));
if(NULL == http_req || NULL == phttp)
{
return -1;
}
char *p = strtok(http_req," ");
if(NULL == p)
{
return -1;
}
strcpy(phttp->method,p);
p = strtok(NULL," ");
if(NULL == p)
{
return -1;
}
strcpy(phttp->url,p);
p = strtok(NULL,"\0");
if(NULL == p)
{
return -1;
}
p = strstr(p,"\r\n\r\n");
if(NULL == p)
{
return -1;
}
if(strcmp(p+4,"commodity"))
{
char old_buf[1024] = {0};
strcpy(old_buf,p + 14);
char new_buf[1024] = {0};
urlDecode(new_buf,old_buf);
printf("%s\n",new_buf);
strcpy(phttp->content,new_buf);
}
else
{
strcpy(phttp->content,p +4);
}
return 0;
}
int callback(void *arg,int column_cnt,char **column_value,char **column_name)
{
printf("**********%s********\n",column_value[0]);
char buf[1024] = {0};
sprintf(buf,"<a href= 'describe.html?goods_sn=%s'><img src=\"./%s\"></a>",column_value[1],column_value[0]);
ssize_t size = send(lead,buf,strlen(buf),0);
if(size < 0)
{
perror("fail send");
return -1;
}
return 0;
}
int callback1(void *arg,int column_cnt,char **column_value,char **column_name)
{
char buf[40960] = {0};
sprintf(buf,"<img border=\"0\" src=\"%s\" alt=\"%s\">\n"
"<p>%s</p>\n""<p>%s</p>\n"
"<p>%s</p>",column_value[20],column_value[3],column_value[16],column_value[18],column_value[11]);
ssize_t size = send(lead,buf,strlen(buf),0);
if(size < 0)
{
perror("fail send2");
return -1;
}
for(int i = 0;i <column_cnt;++i)
{
}
return 0;
}
int find_pictures(int connfd,char file[1024],char *name)
{
sqlite3 *pdb;
int ret = sqlite3_open("./123.db",&pdb);
if(ret != SQLITE_OK)
{
fprintf(stderr,"sqlite3_exec fail:%s\n",sqlite3_errmsg(pdb));
sqlite3_close(pdb);
return -1;
}
char find[1024] = {0};
sprintf(find,"select goods_img,goods_sn from goods where goods_name like \"%%%s%%\";",name);
char *sql = find;
printf("sql = %s\n", sql);
ret = sqlite3_exec(pdb,sql,callback,NULL,NULL);
if (ret != SQLITE_OK)
{
fprintf(stderr,"sqlite3_exec fail : %s\n", sqlite3_errmsg(pdb));
sqlite3_close(pdb);
return -1;
}
sqlite3_close(pdb);
return 0;
}
int find_detail(int connfd,char file[1024],char *name)
{
sqlite3 *pdb;
int ret = sqlite3_open("./123.db",&pdb);
if(ret != SQLITE_OK)
{
fprintf(stderr,"sqlite3_open fail:%s\n",sqlite3_errmsg(pdb));
sqlite3_close(pdb);
return -1;
}
char find[1024] = {0};
sprintf(find,"select * from goods where goods_sn = \"%s\";",name);
char *sql = find;
printf("**************%s\n",sql);
ret = sqlite3_exec(pdb,sql,callback1,NULL,NULL);
if (ret != SQLITE_OK)
{
fprintf(stderr,"sqlite3_exec fail : %s\n", sqlite3_errmsg(pdb));
sqlite3_close(pdb);
return -1;
}
sqlite3_close(pdb);
return 0;
}
int send_http_head(int connfd)
{
char *phead = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html;charset=utf-8\r\n"
"Server: my-web-server\r\n"
"Connection: keep-alive\r\n\r\n";
ssize_t size = send(connfd,phead,strlen(phead),0);
if(size <= 0)
{
perror("send http_head fail");
return -1;
}
return 0;
}
int send_http_file(int connfd,char *filename)
{
char buf[1024] = {0};
int fd = open(filename,O_RDONLY);
if(fd <= 0)
{
perror("fail open file");
return -1;
}
while(1)
{
ssize_t size = read(fd,buf,sizeof(buf));
if(size <= 0)
{
break;
}
send(connfd,buf,size,0);
}
close(fd);
return 0;
}
int send_http_response(int connfd,HTTP_REQ_text *phttp)
{
char file[1024] = {0};
send_http_head(connfd);
char *q= phttp->url;
char *p;
p = strtok(phttp->url,"?");
q = strtok(NULL,"\0");
printf("****%s\n",q);
if(!strcmp(phttp->method,"GET"))
{
if(!strcmp(phttp->url,"/"))
{
sprintf(file,"./resorce/html sorce/login.html");
send_http_file(connfd,file);
return 0;
}
else if(strstr(phttp->url,".jpg") || strstr(phttp->url,".png"))
{
sprintf(file,"./%s",phttp->url);
send_http_file(connfd,file);
return 0;
}
else if(!strcmp(phttp->url,"/favicon.ico"))
{
return 0;
}
else if(strstr(phttp->url,"ECS"))
{
int i = 1;
sprintf(file,"./%s",phttp->url);
send_http_file(connfd,file);
return 0;
}
else if(strstr(phttp->url,"/describe.html"))
{
sprintf(file,"./resorce/html sorce/%s",phttp->url);
send_http_file(connfd,file);
//find_detail(connfd,file,name_buf);
char *address;
address= index(q,'E');
printf("address = %s\n",address);
find_detail(connfd,file,address);
return 0;
}
}
else if(!strcmp(phttp->method,"POST"))
{
if(!strcmp(phttp->url,"/find.html"))
{
sprintf(file,"./resorce/html sorce%s",phttp->url);
send_http_file(connfd,file);
return 0;
}else if(!strcmp(phttp->url,"/commodity.html"))
{
sprintf(file,"./resorce/html sorce/%s",phttp->url);
send_http_file(connfd,file);
strcpy(name_buf,phttp->content);
//printf("name = %s\n",name_buf);
find_pictures(connfd,file,name_buf);
return 0;
}
}
}