day39 实现在线商品信息的查询系统

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

客户端访问网页,发送请求报文,服务端根据对方的请求报文,发送各种内容



主要负责网络通信
#include<sqlite3.h>
#include"../include/net.h"
#include"../include/log.h"


int init_tcp_ser(const char *ip,unsigned short port)
{
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
    {
        perror("fail socket");
        return -1;
    }

    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(sockfd,(struct sockaddr *)&ser,sizeof(ser));
    if(ret < 0)
    {
        perror("fail bind");
        return -1;
    }

    ret = listen(sockfd,1024);
    if(ret < 0)
    {
        perror("fail listen");
        return -1; 
    }

    write_log(LOG_INFO,"tcp初始化");

    return sockfd;
}


int recv_http_request(int connfd,char *req,int maxlen)
{
    memset(req,0,maxlen);

    ssize_t size = recv(connfd,req,maxlen,0);
    if(size < 0)
    {
        perror("fail recv");
        return size;
    }

    write_log(LOG_INFO,"接收响应报文");

    return size;
}

int parse_http_request(char *req,req_t *phreq)
{
    memset(phreq,0,sizeof(req_t));
    
    char *p = strtok(req," ");
    if(NULL == p)
    {
        return -1;
    } 
    strcpy(phreq -> method,p);

    p = strtok(NULL," ");
    if(NULL == p)
    {
        return -1;
    }
    strcpy(phreq -> url,p);

    p = strtok(NULL,"\0");
    if(NULL == p)
    {
        return -1;
    }
    
    p = strstr(p,"\r\n\r\n");
    if(NULL == p)
    {
        return -1;
    }
    strcpy(phreq -> content,p + 4);

    write_log(LOG_INFO,"解码中");

    return 0;
}

int send_http_request_head(int connfd)
{
    char *presp = "HTTP/1.1 200 0K\r\n"
                "Content-Type: text/html;charset=utf-8\r\n"
                "Server:openresty\r\n"
                "Connection:keep-alive\r\n\r\n";

    ssize_t size = send(connfd,presp,strlen(presp),0);
    if(size < 0)
    {
        perror("fail send");
        return -1;
    }

    write_log(LOG_INFO,"发送响应报文");

    return 0;
}

int send_net_file(int connfd,char *filename)
{
    char buff[1024] = {0};

    int fd = open(filename,O_RDONLY);
    if(fd < 0)
    {
        perror("fail open");
        return -1;
    }

    while(1)
    {
        memset(buff,0,sizeof(buff));

        ssize_t size = read(fd,buff,sizeof(buff));
        if(size <= 0)
        {
            break;
        }
        send(connfd,buff,size,0);
    }

    write_log(LOG_INFO,"发送文件");

    close(fd);

    return 0;
} 

int send_http_response(int connfd,req_t *phreq)
{
    char filename[512] = {0};

    send_http_request_head(connfd);

    if(!strcmp(phreq -> method,"GET"))
    {
        if(!strcmp(phreq -> url,"/"))
        {
            sprintf(filename,"./html/1.html");
            send_net_file(connfd,filename);
        }
        else if(!strcmp(phreq -> url,"/favicon.ico"))
        {
            return 0;
        }
        else if(strstr(phreq -> url,".jpg") || strstr(phreq -> url,".png"))
        {
            sprintf(filename,".%s",phreq -> url);
            send_net_file(connfd,filename);
        } 
        else if(strstr(phreq -> url,".html"))
        {
            char path[64] = {0};
            memset(path,0,sizeof(path));
            strcpy(path,phreq -> url);
 sprintf(filename,"./html/mean.html");
            send_net_file(connfd,filename);

            find1(atoi(phreq->url+11),connfd);
        }
    }
    else if(!strcmp(phreq -> method,"POST"))
    {
        if(strstr(phreq -> url,".html"))
        {
            if(!strcmp(phreq ->url , "/goods.html"))
            {
                sprintf(filename,"./html%s",phreq -> url);
                send_net_file(connfd,filename);
                find(phreq->content,connfd);
            }
            else
            {
                sprintf(filename,"./html%s",phreq -> url);
                send_net_file(connfd,filename);
            }
        }
    }

    return 0;
}







此模块用于在数据库中寻找指定商品
#include<sqlite3.h>
#include"../include/net.h"

unsigned char FromHex(unsigned char x)
{
	if(0 == x ) return -1;
	unsigned char y;
	if(x>='A' &&x<='Z') y = x-'A'+10;
	else if(x>='a' &&x <='z') y = x-'a'+10;
	else if(x>='0' && x<='9') y = x-'0';

	return y;
}

int  urlDecode(  char* dest, const char* src)
{
	if(NULL ==src || NULL == dest)
	{
		return -1;

	}
	int len = strlen(src);
	int i =0 ;
	for(i = 0 ;i<len;i++)
	{

		if('+' == src[i]) strcat(dest,"");
		else if('%'==src[i])
		{
			//if(i+2len)return -1;
			unsigned char high = FromHex((unsigned char)src[++i]);
			unsigned char low = FromHex((unsigned char)src[++i]);
			unsigned char temp = high*16 +low;
			char temp2[5]={0};
			sprintf(temp2,"%c",temp);
			strcat(dest , temp2);
		}
	}
	return 0;
}
int callback(void *arg,int n,char **value,char **name)
{
    int connfd = *(int *)arg;

    char buff[1024] = {0};   

    {
        sprintf(buff,"<tr><td><a href =\"mean.html?%s\" method=\"POST\"><img border=\"0\"src=\"./source/%s\"alt=\"%s\"width=\"100\"height=\"100\"></a></td>><td>%s</td></tr>",value[0],value[20],"goods.html",value[3]); 
    }
 
    send(connfd,buff,strlen(buff),0);

    return 0;
}

int find(char *phone,int connfd)
{
    sqlite3 *pdb;
    int ret = sqlite3_open("./source/123.db",&pdb);
    if(ret != SQLITE_OK)
    {
        fprintf(stderr,"fail open:%s\n",sqlite3_errmsg(pdb));
        return -1;
    }

    char new_buff[128] ={0};
    char size[1024] = {0};
    
    urlDecode(new_buff,phone); 

    sprintf(size,"select * from goods where goods_name like \"%s%%\";",new_buff); 

    ret = sqlite3_exec(pdb,size,callback,&connfd,NULL);
    if(ret != SQLITE_OK)
    {
        fprintf(stderr,"fail sqlite3_exec:%s\n",sqlite3_errmsg(pdb));
        return -1;
    }
  
    sqlite3_close(pdb);

    return 0;
}


int callback1(void *arg,int n,char **value,char **name)
{
    int connfd = *(int *)arg;

    char buff[102400] = {0}; 

    {
        printf("%s=%s\n",name[3],value[3]);
        
        sprintf(buff,"<img src=\"../source/%s\" alt=\"商品\" class=\"product-image\"><h1 class=\"product-title\">%s</h1><p class=\"product-description\">%s</p ><p class=\"p\">市场价格:%s</p ><p class=\"product-price\">商场价格:%s</p ></div></body></html>",value[20],value[3],value[18],value[10],value[11]);
       
    }
  
    send(connfd,buff,strlen(buff),0);

    return 0;
}

int find1(int id,int connfd)
{
    printf("id = %d",id);
    sqlite3 *pdb;
    int ret = sqlite3_open("./source/123.db",&pdb);
    if(ret != SQLITE_OK)
    {
        fprintf(stderr,"fail open:%s\n",sqlite3_errmsg(pdb));
        return -1;
    }

    char size[1024] = {0};

    sprintf(size,"select * from goods where goods_id=\"%d\";",id); 

        printf("size =%s\n",size);
    ret = sqlite3_exec(pdb,size,callback1,&connfd,NULL);
    if(ret != SQLITE_OK)
    {
        fprintf(stderr,"fail sqlite3_exec:%s\n",sqlite3_errmsg(pdb));
        return -1;
    }

epooll模块
#include"../include/net.h"

int epoll_add_fd(int eptds ,int fd, uint32_t events)
{
    struct epoll_event ev;
    ev.events = events;
    ev.data.fd = fd;
    int ret = epoll_ctl(eptds,EPOLL_CTL_ADD,fd,&ev);
    if(ret < 0)
    {
        perror("fail epoll_ctl add");
        return -1;
    }
    return 0;
}


int epoll_DEL_fd(int eptds ,int fd, uint32_t events)
{
    struct epoll_event ev;
    ev.events = events;
    ev.data.fd = fd;
    int ret = epoll_ctl(eptds,EPOLL_CTL_DEL,fd,&ev);
    if(ret < 0)
    {
        perror("fail epoll_ctl add");
        return -1;
    }
    return 0;
}

日志模块
 "../include/log.h"
#include <sys/stat.h>
#include <sys/types.h>


log_s log_g;//全局结构体变量
int init_log()//初始化函数
{
    struct tm *ptm = NULL;
    time_t sec = time(NULL);
    ptm = localtime(&sec);
    log_g.time = *ptm;
    
    char filename[256] = {0};//村名字进去不能用char*
    mkdir("LOG",0777);//创建目录
    sprintf(filename,"./LOG/log%d-%02d-%02d.txt",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday);//在LOG目录下创建文件
    log_g.fp = fopen(filename,"a");
    if(log_g.fp == NULL)
    {
        printf("fopen fail!\n");
        return -1;
    }
    return 0;
    
}

int write_log(log_lev lev,char *str)
{
    time_t sec = time(NULL);
    struct tm *ptm = NULL;
    ptm = localtime(&sec);

    if(ptm->tm_mday != log_g.time.tm_mday)
   // if(ptm->tm_min != log_g.time.tm_min)
    {
        deinit_log();
        init_log();
    }
    char *leves[3] = {"LOG_INFO","LOG_WARN","LOG_ERR"};//由于枚举成员本质是整数,传递不了他代表的字符串,创建字符串数组,用枚举常量表示下标;
    fprintf(log_g.fp,"[%d-%d-%d %d:%d;%d][%s]%s\n",ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,
            ptm->tm_hour,ptm->tm_min,ptm->tm_sec,leves[lev],str);
    fflush(log_g.fp);
    return 0;
}

void deinit_log()
{
    fclose(log_g.fp);
}



多路tcp
main函数
#include"../include/net.h"
#include "../include/log.h"
int main(int argc,char *argv[])
{
    init_log();

    write_log(LOG_INFO,"日志模块初始化成功!");
    char req[1024] = {0};
    req_t  hreq;
    int sockfd = init_tcp_ser("192.168.0.179",8080);
    if (sockfd < 0)
    {
        return -1;
    }

    int maxfd = 0;
    int epfds = epoll_create(10000);//创建描述符集合最大10
    if(epfds < 0)
    {
        perror("fail epoll_create");
        return -1;
    }
    //添加描述符
    epoll_add_fd(epfds,sockfd,EPOLLIN);
    struct epoll_event evs[10];
    while(1)
    {
     #if 0
        int connfd = accept(sockfd,NULL,NULL);
        if(connfd < 0)
        {
            perror("fail accept");
            return -1;
             write_log(LOG_ERR,"accept失败!");
        }

        write_log(LOG_INFO,"与客户端accept成功");
        int ret =  recv_http_request(connfd,req,sizeof(req));//不传长度指针无法计算长度

        if(ret < 0)
        {
            return -1;
        }

        ret = parse_http_request(req,&hreq);
        if(ret < 0)
        {
            return -1;
        }
        printf("method : %s\n", hreq.method);
        printf("url: %s\n", hreq.url);
        printf("content : %s\n", hreq.content);

        send_http_response(connfd, &hreq);

        close(connfd);
#endif

        int cnt = epoll_wait(epfds,evs,10,-1);
        if(cnt < 0)
        {
            perror("fail epoll wait");
            return -1;
        }

        for(int i = 0;i <cnt;i++)
        {
            if(evs[i].data.fd==sockfd)
            {
                int connfd=accept(sockfd,NULL,NULL);
                if(connfd < 0)
                {
                    write_log(LOG_ERR,"accept失败!");
                    perror("fail accept");
                    return -1;
                }
                write_log(LOG_INFO,"与客户端accept成功");
                epoll_add_fd(epfds,connfd,EPOLLIN);
                write_log(LOG_INFO,"epoll添加套接字");
            }
            else
            {
                printf("connfd_evs= %d\n",evs[i].data.fd);
                int ret =  recv_http_request(evs[i].data.fd,req,sizeof(req));//不传长度指针无法计算长度

                if(ret < 0)
                {
                    return -1;
                }

                ret = parse_http_request(req,&hreq);
                if(ret < 0)
                {
                    return -1;
                }
                printf("method : %s\n", hreq.method);
                printf("url: %s\n", hreq.url);
                printf("content : %s\n", hreq.content);

                send_http_response(evs[i].data.fd, &hreq);
                epoll_DEL_fd(epfds,evs[i].data.fd,EPOLLIN);
                write_log(LOG_INFO,"epoll删除套接字");
                close(evs[i].data.fd);

            }

        }
    }
    close(sockfd);
    return 0;
}




以及HTML文件
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值