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

网页html版——在线查字典的一个web服务器

HTML(HyperText Markup Language)

HTML是一种用于创建网页的标准标记语言。可以用dreamwave这个工具来写

使用文本编辑器(如Notepad++、Sublime Text、Visual Studio Code等)创建一个新的文件,并将其保存为 .html 文件。

1.格式

<!DOCTYPE html>
<html >
	<head>
		<meta charset="utf-8">
		<title>中文测试。。。。</title>
	</head>
	<body>
		这里是测试body测试内容。。。
	</body>
</html>

文档类型声明 (<!DOCTYPE html>):告诉浏览器这是一个HTML5文档。

 根元素 (<html>):包含整个HTML文档的所有内容。

 文档头部 (<head>):包含了文档的元数据,比如字符集设置、视口设置以及文档的标题。

 字符集 (<meta charset="UTF-8">):设置文档的字符编码为UTF-8。 

标题 (<title>):显示在浏览器标签页上的文本

主体 (<body>):包含网页的所有可见内容。

2.标签

在body内
<h1></h1>双标签 标题 ,加粗,换行  1-6 ---》小
<p></p> 双标签  段落,有换行功效
<hr> 单标签  左到右分割符
<!--    -->注释

3.元素的属性

给元素提供更多的属性,大部分的元素属性
语法:<标签 属性1=参数1 属性2=参数2>
1)align left,right,center
2) bgcolor ,body的属性设置网页的背景色
<body bgcolor="0xff1234" bgcolor="0xff1234">

4.文本元素属性

b 元素 <b>内容</b> 加粗
br 换行<br> 如果是p标签中间有间隔
i元素, 字体倾斜<i></i>
del元素 删除文字<del></del>
strong  强调一段文字,效果类似 b标签
u元素,下划线<u></u>
small元素, 超小字体<small></small>
sub 下标<sub></sub>
sup  上标<sup></sup>
<br>h<sub>2</sub>0
<br>100m<sup>2</sup>
ruby,拼音,<ruby>二姐 <rt>(er) (jie)<rt></ruby>,可能部分浏览器不支持。
mark 元素 <mark> </mark> 加黄色背景

5.超链接

5种形式
1,链接外部网站
2,链接本地文件
3,图片链接
4,电子邮件链接打开电子邮件
5,下载文件链接

        <a href="http://www.baidu.com">baidu</a>
        <br><a href="1.html">1111</a>
        <br><a href="1.html"><img src="abc.jpg"></a>
        <br><a href="mailto:123@13.com">contract me</a>
        <br><a href="abc.jpg">下载</a>
上面的方法在打开新网页时,老的网页会关闭
target 属性
_self :当前位置打开 默认值
_blank 新窗口中打开
<a href="http://www.baidu.com" target="_blank">baidu</a>

字符串处理函数strtok、strstr

strtok

用于将一个字符串分割成多个子字符串(标记)。strtok 函数通常用于解析文本数据,例如从逗号分隔的字符串中提取各个字段。

char *strtok(char *str, const char *delim);

str:指向要分割的字符串的指针。

delim:包含一个或多个分隔符的字符串。

返回值         如果成功分割出一个子字符串,strtok 返回指向该子字符串的指针。

                    如果没有更多的子字符串可分割,strtok 返回 NULL。

重复调用:strtok 函数需要重复调用来获取所有的子字符串。

                首次调用时,str 应该指向原始字符串;

                后续调用时,str 应该为 NULL,delim 应该保持不变。

#include <stdio.h>
#include <string.h>

int main() {
    char str[] = "Name,Age,Occupation\nJohn,30,Developer\nJane,28,Designer";
    const char *delimiters = "\n,";

    char *line = strtok(str, "\n");  // 按行分割
    while (line != NULL) {
        printf("Line: %s\n", line);

        char *field = strtok(line, ",");  // 按字段分割
        while (field != NULL) {
            printf("Field: %s\n", field);
            field = strtok(NULL, ",");
        }

        line = strtok(NULL, "\n");  // 下一行
    }

    return 0;
}

strstr

用于在一个字符串中查找另一个字符串首次出现的位置。

如果找到了子字符串,strstr 将返回指向该子字符串的第一个字符的指针;

如果没有找到,则返回 NULL。

char *strstr(const char *haystack, const char *needle);

haystack:要搜索的字符串的指针。

needle:指向要查找的子字符串的指针。

#include <stdio.h>
#include <string.h>

int main() {
    const char *haystack = "Hello, world! Welcome to the programming world.";
    const char *needle = "world";

    // 查找子字符串
    char *found = strstr(haystack, needle);

    if (found != NULL) {
        printf("Found substring '%s' at position %ld.\n", needle, found - haystack);
    } else {
        printf("Substring '%s' not found.\n", needle);
    }

    return 0;
}

access()

用于检查指定文件的访问权限。

它可以用来判断一个文件是否存在,以及当前进程是否有权对该文件执行特定类型的访问。

#include <unistd.h>

int access(const char *pathname, int mode);

pathname:指向文件路径的字符串指针。

mode:指定要检查的访问模式,可以是以下常量之一或它们的按位或组合:

F_OK:文件存在即可。

R_OK:文件可读。

W_OK:文件可写。

X_OK:文件可执行。

返回值

如果检查成功,access() 返回 0。

如果检查失败,access() 返回 -1,并且设置 errno 为相应的错误码。

if(access("dict.db",F_OK))
      {
          LoadDictToDB();
      }          

memset()

用于将一块内存区域中的每个字节都设置为同一个值。这个函数通常用于初始化内存块,清零缓冲区

#include <string.h>

void *memset(void *ptr, int value, size_t num);

// 使用 memset 将缓冲区初始化为 0
memset(buffer, 0, sizeof(buffer));

ptr:指向要填充的内存区域的指针。

value:要设置到每个字节的值。注意,这个值会被转换为无符号字符类型 unsigned char。

num:要填充的字节数。

#ifndef __HEAD_H__
#define __HEAD_H__

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <sqlite3.h>

/* HTTP请求报文解析信息 */
typedef struct httprequest{
	char *pmethod;							//方法
	char *purl;								//请求资源路径
	char *pcontent;							//正文
}httprequest_t; 

/* 查询单词结果类型 */
typedef struct callbackarg
{
	char mean[4096];						//单词含义
	int flag;								//是否被找到标志
}arg_t;

#endif


 

#include"head.h"


int LoadDictToDB(void)
{
	sqlite3 *pdb = NULL;
	char cmdbuf[4096] = {0};
	int ret = 0;
	char *perrmsg = NULL;
	FILE *fp = NULL;
	char tmpbuff[4096] = {0};
	char *pret = NULL;
	char *ptmpword =NULL;
	char *ptmpmean = NULL;
	long len = 0;
	long curlen = 0;

	ret = sqlite3_open("dict.db",&pdb);
	if(ret != SQLITE_OK)
	{
		fprintf(stderr,"fail to sqlite3_open:%s\n",sqlite3_errmsg(pdb));
		return -1;
	}

	sprintf(cmdbuf,"create table if not exists dict (number integer primary key asc,Word varchar(64),Mean varchar(4096));");
	ret = sqlite3_exec(pdb,cmdbuf,NULL,NULL,&perrmsg);
	if(ret!= SQLITE_OK)
	{
		fprintf(stderr,"fail to sqlite3_exec%s\n",perrmsg);
		sqlite3_free(perrmsg);
		sqlite3_close(pdb);
		return -1;
	}

	fp = fopen("dict.txt","r");
	if(NULL == fp)
	{
		perror("fail to open");
		return -1;
	}

	fseek(fp,0,SEEK_END);
	len = ftell(fp);
	rewind(fp);

	while(1)
	{
		pret = fgets(tmpbuff,sizeof(tmpbuff),fp);
		if(NULL == pret)
		{
			break;
		}

		curlen = ftell(fp);
		printf("已加载%.2lf%%\r",(double)curlen/(double)len*100);
		fflush(stdout);

		ptmpword = strtok(tmpbuff," ");
		ptmpmean = strtok(NULL,"\r");
		sprintf(cmdbuf,"insert into dict values(NULL,\"%s\",\"%s\");",ptmpword,ptmpmean);
		ret = sqlite3_exec(pdb,cmdbuf,NULL,NULL,&perrmsg);
		if(ret!=SQLITE_OK)
		{
			fprintf(stderr,"fail to sqlite3_exec:%s\n",perrmsg);
			sqlite3_free(perrmsg);
			sqlite3_close(pdb);
			return -1;
		}
	}
	sqlite3_close(pdb);

	return 0;
}


int callback(void *arg,int col,char **pcontent,char **ptitle)
{
	arg_t *pmeanmsg = arg;
	pmeanmsg->flag = 1;
	strcpy(pmeanmsg->mean,pcontent[0]);

	return 0;
}

int FindWordMean(char *pword,arg_t *pmeanmsg)
{
	sqlite3 *pdb = NULL;
	char cmdbuf[4096] = {0};
	int ret = 0;
	char *perrmsg = NULL;

	ret = sqlite3_open("dict.db",&pdb);
	if(ret!= SQLITE_OK)
	{
		fprintf(stderr,"fail to sqlite3_open:%s\n",sqlite3_errmsg(pdb));
		return -1;
	}
	
	memset(pmeanmsg,0,sizeof(*pmeanmsg));
	sprintf(cmdbuf,"select Mean from dict where Word =\"%s\";",pword);
	ret = sqlite3_exec(pdb,cmdbuf,callback,pmeanmsg,&perrmsg);
	if(ret!=SQLITE_OK)
	{
		fprintf(stderr,"fail to sqlite3_exec:%s\n",perrmsg);
		sqlite3_free(perrmsg);
		sqlite3_close(pdb);
		return -1;
	}

	sqlite3_close(pdb);
	return 0;

}



int CreateListenSocket(char *pip,int port)
{
	int ret = 0;
	int sockfd = 0;
	struct sockaddr_in seraddr;

	sockfd = socket(AF_INET,SOCK_STREAM,0);
	if(-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}

	seraddr.sin_family = AF_INET;
	seraddr.sin_port = htons(port);
	seraddr.sin_addr.s_addr = inet_addr(pip);
	ret = bind(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr));
	if(-1 == ret)
	{
		perror("fail to listen");
		return -1;
	}

	ret = listen(sockfd,10);
	if(-1 == ret)
	{
		perror("fail to listen");
		return -1;
	}

	return sockfd;
}

int RecvHttpRequest(int confd,char *precvbuffer,int maxlen)
{
	ssize_t nsize = 0;

	memset(precvbuffer,0,maxlen);
	nsize = recv(confd,precvbuffer,maxlen,0);
	if(-1 == nsize)
	{
		perror("fail to recv");
		return -1;
	}

	printf("==============RECV============\n");
	printf("%s\n",precvbuffer);
	printf("==============================\n");

	return nsize;
}

int SpliteHttpRequest(char *precvbuffer,httprequest_t *ptmprequest)
{
	char *pmethod = NULL;
	char *purl = NULL;
	
	ptmprequest->pcontent = strstr(precvbuffer,"\r\n\r\n")+4;
	ptmprequest->pmethod = strtok(precvbuffer," ");
	ptmprequest->purl = strtok(NULL," ");

	return 0;
}

int SendHttpResponseSuccessHeader(int confd)
{
	char tmpbuff[4096] = {0};
	ssize_t nsize = 0;

	sprintf(tmpbuff,"HTTP/1.1 200 OK\r\n");
	sprintf(tmpbuff,"%sconnection:Keep-alive\r\n\r\n",tmpbuff);

	nsize = send(confd,tmpbuff,strlen(tmpbuff),0);
	if(nsize <= 0);
	{
		perror("fail to sned");
		return -1;
	}

	return 0;
}


int SendHttpResponseFailureHeader(int confd)
{
	char tmpbuff[4096] = {0};
	ssize_t nsize = 0;

	sprintf(tmpbuff,"HTTP/1.1 404 NotFound\r\n");
	sprintf(tmpbuff,"%sconnection:close\r\n\r\n",tmpbuff);

	nsize = send(confd,tmpbuff,strlen(tmpbuff),0);
	if(nsize <= 0);
	{
		perror("fail to send");
		return -1;
	}

	return 0;
}

int SendHttpResponseHtml(int confd,char *presourcepath)
{
	int fd = 0;
	char tmpbuff[4096] = {0};
	ssize_t nsize = 0;
	ssize_t nret = 0;

	fd = open(presourcepath,O_RDONLY);
	if(-1 == fd)
	{
		perror("fail to open");
		return -1;
	}

	while(1)
	{
		nsize = read(fd,tmpbuff,sizeof(tmpbuff));
		if(nsize<=0)
		{
			break;
		}

		nret = send(confd,tmpbuff,nsize,0);
		if(-1 == nret)
		{
			perror("fail to send");
			break;
		}
	}

	close(fd);
	return 0;
}

int SpliteSearchWordValue(char *pcontent,char *pword,int maxlen)
{
	strtok(pcontent,"=");
	strncpy(pword,strtok(NULL,"="),maxlen-1);

	return 0;
}

int GenerateWordMeanHtml(char *htmlpath,char *pmean)
{
	FILE *fp = NULL;

	fp = fopen(htmlpath,"w");
	if(NULL == fp)
	{
		perror("fail to fopen");
		return -1;
	}

	fprintf(fp,"<html>\n");
	fprintf(fp,"<head>\n");
	fprintf(fp,"</head>\n");

	fprintf(fp,"<body>\n");
	fprintf(fp,"%s\n",pmean);
	fprintf(fp,"</body>\n");
	fprintf(fp,"</html>\n");

	fclose(fp);
	return 0;
}


int SendHttpResponse(int confd,httprequest_t tmprequest)
{
	char resourcepath[512] = {0};
	char word[512] = {0};
	arg_t meanmsg;

	if(!strcmp(tmprequest.pmethod,"GET"))
	{
		//如果 tmprequest.purl  是 /  则strcmp 的返回值是0   取反 变成1  进入if语句中
		if(!strcmp(tmprequest.purl,"/"))   
		{
			sprintf(resourcepath,"www/index.html");
		}
		else if(!strcmp(tmprequest.purl,"/favion.ico")) // 这个是请求网站图标  我们没有所以直接返回0 退出
		{
			return 0;
		}
		else
		{
			sprintf(resourcepath,"www%s",tmprequest.purl);
		}

		if(0 == access(resourcepath,F_OK))
		{
			SendHttpResponseSuccessHeader(confd);
			SendHttpResponseHtml(confd,resourcepath);
		}
		else
		{
			SendHttpResponseFailureHeader(confd);
			return 0;
		}
	}

	else if(!strcmp(tmprequest.pmethod,"POST"))
	{
		if(!strcmp(tmprequest.purl,"/searchword"))
		{
			SpliteSearchWordValue(tmprequest.pcontent,word,512);
			FindWordMean(word,&meanmsg);

			printf("pmeanmsg.flag=%d\n",meanmsg.flag);
			if(meanmsg.flag)
			{
				GenerateWordMeanHtml("www/mean.html",meanmsg.mean);
			}
			else
			{
				GenerateWordMeanHtml("www/mean.html","can not find this word");
			}
			SendHttpResponseSuccessHeader(confd);
			SendHttpResponseHtml(confd,"www/mean.html");
		}
	}

	return 0;


}

int main(int argc, const char *argv[])
{
	int confd = 0;
	int sockfd = 0;
	char recvbuffer[4096] = {0};
	httprequest_t request;  // 请求报文解析出的各类信息 结构体
	char word[256] = {0}; 

	if(access("dict.db",F_OK))
	{
		LoadDictToDB();
	}

	sockfd = CreateListenSocket("192.168.95.131",8080);//创建服务器

	while(1)
	{
		//当服务器监听某个端口 并收到客户端的连接请求时,accept函数就会被调用
		//accept成功被调用时,会返回一个新的socket套接字,这个套接字用于与特定的客户端通信
		confd = accept(sockfd,NULL,NULL);   
		if(-1 == confd)
		{
			perror("fail to accept");
			return -1;
		}

		RecvHttpRequest(confd,recvbuffer,4096);//接收http 请求报文
		SpliteHttpRequest(recvbuffer,&request);//对请求报文进行拆分解析 并把解析出的信息放入request结构体中
		SendHttpResponse(confd,request);//回复响应报文
		close(confd);//释放tcp连接
	}

	return 0;
}


http://www.kler.cn/news/284997.html

相关文章:

  • Android 移除最近任务列表展示
  • CSND文章质量分批量查询
  • 类图的关联关系
  • Python基础 3 - 函数及数据容器
  • JAVA毕业设计167—基于Java+Springboot+vue3+小程序的物业管理系统小程序(源代码+数据库+万字论文+文献综述)
  • Llamaindex RAG实践
  • 并发服务器
  • 代码随想录算法训练营第六十天 | 图论part10
  • SkyWalking部署(监控系统)
  • jquery下载的例子如何应用到vue中
  • 【秋招笔试】8.30饿了么秋招(算法岗)-三语言题解
  • MongoDB 中国用户大会8月31日 (MongoDB 8.0 发布)
  • 医院建筑的电气设计——保障医疗质量与安全的坚固基石
  • 深度学习100问20:什么是RNN
  • GPT带我学-设计模式-责任链模式
  • 力扣面试150 插入区间 模拟
  • 【经典面试题】Kafka为什么这么快?
  • Qt: QGraphicsView二维图形绘图框架
  • sql 4,创建表类型
  • HTML <template> 标签的基本技巧
  • flutter 开发中常用的 Widget
  • Metasploit漏洞利用系列(十):MSF渗透测试 - 震网三代(远程快捷方式漏洞)实战
  • Elasticsearch中别名的作用
  • .NET WPF 抖动动画
  • python 天气与股票的关系--第一部分,爬取数据
  • 新审视零阶优化在内存高效大模型微调中的应用
  • 你是如何克服编程学习中的挫折感的?——从Bug中找到成长的契机
  • Linux awk案例
  • Dataworks_PySpark开发流程
  • azure-search-openai-demo-csharp does not deploy correctly to azure clooad