词典项目练习

 思维导图

 客户端

#include "head.h"
//用户提示界面
void help_info1()
{
	printf("\t-----------------------------------------------\n");
	printf("\t|               HENRY   在线辞典               |\n");
	printf("\t|版本:0.0.1                                    |\n");
	printf("\t|作者:Demons457                                |\n");
	printf("\t|功能:                                         |\n");
	printf("\t|    [1] 登录                                  |\n");
	printf("\t|    [2] 注册                                  |\n");
	printf("\t|    [3] 退出                                  |\n");
	printf("\t|注意:用户只有登录成功后才能进入查单词界面     |\n");
	printf("\t------------------------------------------------\n");
	return;
}
void help_info2()
{
	printf("\t-----------------------------------------------\n");
	printf("\t|     欢迎进入单词查询系统,很高兴为您服务     |\n");
	printf("\t|版本:0.0.1                                    |\n");
	printf("\t|作者:Demons457                                |\n");
	printf("\t|功能:                                         |\n");
	printf("\t|    [1] 查单词                                |\n");
	printf("\t|    [2] 查询历史记录                          |\n");
	printf("\t|    [3] 退出查询系统                          |\n");
	printf("\t|注意:用户只有登录成功后才能进入查单词界面     |\n");
	printf("\t------------------------------------------------\n");
	return;
}
 
 
//用户输入指令
enum{
	LOGIN    = 1,  //登陆
	REGISTER = 2,  //注册
	QUIT     = 3,  //退出
	QUERY    = 1,  //查询单词
	HISTORY  = 2,  //查询历史
};
 
int init_tcp(char *ip,char *port)
{
	int sockfd;
	struct sockaddr_in server_addr;
 
	if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
	{
		perror("Fail to socket");	
		exit(EXIT_FAILURE);
	}
 
	bzero(&server_addr,sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(atoi(port));
	server_addr.sin_addr.s_addr = inet_addr(ip);
 
	if(connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
	{
		perror("Fail to bind");	
		exit(EXIT_FAILURE);
	}
 
	return sockfd;
}
 
int do_register(int sockfd)
{
	int n = 0;
	int count = 0;
	char buf[1024] = {0};
	//定义发送的协议头
	mhead_t *head = (mhead_t *)buf;
 
	printf("\n您正在注册,请输入用户名和密码\n");
 
	head->type = USER_REGISTER;
	head->size = sizeof(mhead_t);
 
	printf("Input username : ");
	fgets(head->username,sizeof(head->username),stdin);
	head->username[strlen(head->username) - 1] = '\0';
 
	printf("Input password : ");
	fgets(head->password,sizeof(head->password),stdin);
	head->password[strlen(head->password) - 1] = '\0';
 
	//发给服务器端
	
	if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
	{
		perror("Fail to send");
		exit(EXIT_FAILURE);
	}
	
	bzero(&buf,sizeof(buf));
	while(1)
	{
		//接收数据,TCP是可靠的连接,若是数据
		//未完全接收的话,可以在接收
		n = recv(sockfd,buf + count,sizeof(mhead_t) - count,0);
 
		if(n <= 0){
			perror("Fail to send");
			exit(EXIT_FAILURE);
		}
		//若是数据未发送完成,再次接收的时候可补充
		count += n;
		if(count == sizeof(mhead_t))
			break;
	}
 
	if(head->type == USER_SUCCESS)
	{
		printf("\n恭喜您,注册成功!\n");	
		return 0;
	}else{
		printf("\n很遗憾,这个用户名已经被其它用户注册过了,请重新注册");	
		return -1;
	}
 
}
int do_query(int sockfd)
{
	int n = 0;
	int fd;
	int count = 0;
	char buf[1024] = {0};
	char buf1[128]={0};
	char buf2[128]={0};
	char buf3[]="\n";
	fd=open("/home/linux/22061/2/client/history.txt",O_RDWR|O_CREAT|O_TRUNC,0666);
	if(fd<0)
	{
	 perror("Fail to open");
	 return -1;
	}
	//定义发送的协议头
	mhead_t *head = (mhead_t *)buf;
 
	printf("\n您正在查询单词\n");
 
	head->type = USER_WORD;
	head->size = sizeof(mhead_t);
 
	printf("pelse input word : ");
	fgets(head->word,sizeof(head->word),stdin);
	head->word[strlen(head->word) - 1] = '\0';
    strcpy(buf1,head->word);
	if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
	{
		perror("Fail to send");
		exit(EXIT_FAILURE);
	}
	
	bzero(&buf,sizeof(buf));
	while(1)
	{
		//接收数据
		//未完全接收的话,可以在接收
		n = recv(sockfd,buf + count,sizeof(mhead_t) - count,0);
 
		if(n <= 0){
			perror("Fail to send");
			exit(EXIT_FAILURE);
		}
		//若是数据未发送完成,再次接收的时候可补充
		count += n;
		if(count == sizeof(mhead_t))
			break;
	}
  //把服务器返回的信息打印出来
 	if(head->type == USER_SUCCESS)
	{
		printf(" word:%s\n",head->word);	
		time_t t;
		time(&t);
		sprintf(buf2,"\n%s\n",ctime(&t));
		write(fd,buf1,strlen(buf1));
		write(fd,buf2,strlen(buf2));
		write(fd,head->word,strlen(head->word));
		write(fd,buf3,strlen(buf3));
		close(fd);
		return 0;
	}else{
		printf("\n很遗憾,没有此单词,请重新输入\n");	
		return -1;
	}
   
}
int do_history(int sockfd)
{
  int fd,n;
  char buf[1024]={0};
  fd=open("/home/linux/22061/2/client/history.txt",O_RDONLY);
  if(fd<0)
  {
   perror("Fail to open");
   return -1;
  }
  while(1)
  {
   n=read(fd,buf,sizeof(buf));
   if(0==n)
	   break;
   puts(buf);
  }
  return 0;
}
int do_task2(int sockfd)
{
	int cmd;
	while(1)
	{
		//提示界面帮助,用户选择
		help_info2();	
 
		printf("\n\n请选择>");
		scanf("%d",&cmd);
		//吃掉回车键
		getchar();
		switch(cmd)
		{
			//用户查询单词
			case QUERY:
				if(do_query(sockfd) < 0)
					continue;
					break;
			//用户登陆
			case HISTORY:
					if(do_history(sockfd)<0)
					continue;
					 break;
			case QUIT:
				exit(EXIT_SUCCESS);
			default:
				printf("Unknow cmd.\n");
				continue;
		}
	}
	return 0;
}
 
int do_login(int sockfd)
{
	int n = 0;
	int count = 0;
	char buf[1024] = {0};
	//定义发送的协议头
	mhead_t *head = (mhead_t *)buf;
 
	printf("\n您正在登陆,请输入用户名和密码\n");
 
	head->type = USER_LOGIN;
	head->size = sizeof(mhead_t);
 
	printf("Input username : ");
	fgets(head->username,sizeof(head->username),stdin);
	head->username[strlen(head->username) - 1] = '\0';
 
	printf("Input password : ");
	fgets(head->password,sizeof(head->password),stdin);
	head->password[strlen(head->password) - 1] = '\0';
 
	//发给服务器端
	
	if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
	{
		perror("Fail to send");
		exit(EXIT_FAILURE);
	}
	
	bzero(&buf,sizeof(buf));
	while(1)
	{
		//接收数据
		//未完全接收的话
		n = recv(sockfd,buf + count,sizeof(mhead_t) - count,0);
 
		if(n <= 0){
			perror("Fail to send");
			exit(EXIT_FAILURE);
		}
		//若是数据未发送完成,再次接收的时候可补充
		count += n;
		if(count == sizeof(mhead_t))
			break;
	}
 
	if(head->type == USER_SUCCESS)
	{
		printf("\n恭喜您,登陆成功!\n");	
		do_task2(sockfd);
		return 0;
	}else{
		printf("\n很遗憾,您的帐号或密码错误,请重新输入");	
		return -1;
	}
   
 
}
int do_task(int sockfd)
{
	int cmd;
	while(1)
	{
		//提示界面帮助,用户选择
		help_info1();	
 
		printf("\n\n请选择>");
		scanf("%d",&cmd);
		//吃掉回车键
		getchar();
		switch(cmd)
		{
			//用户注册
			case REGISTER:
				if(do_register(sockfd) < 0)
					continue;
					break;
			//用户登陆
			case LOGIN:
					if(do_login(sockfd)<0)
					continue;
					 break;
			case QUIT:
				exit(EXIT_SUCCESS);
			default:
				printf("Unknow cmd.\n");
				continue;
		}
	}
	return 0;
}
 
//由于后面要传递参数
int main(int argc, char *argv[])
{
	int sockfd;	
	int addr_len = sizeof(struct sockaddr);
	struct sockaddr_in peer_addr;
 
	if(argc < 3)
	{
		fprintf(stderr,"Usage : %s argv[1] argv[2]\n",argv[0]);	
		exit(EXIT_FAILURE);
	}
 
	sockfd = init_tcp(argv[1],argv[2]);
 
	do_task(sockfd);
 
	return 0;
}

服务器端

#include "head.h"
 
 
void signal_handler(int signum)
{
	waitpid(-1,NULL,WNOHANG);
	return;
}
int init_tcp(char *ip,char *port)
{
	int sockfd;
	struct sockaddr_in server_addr;
 
	if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
	{
		perror("Fail to socket");
		exit(EXIT_FAILURE);
	}
	bzero(&server_addr,sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port   = htons(atoi(port));
	server_addr.sin_addr.s_addr = inet_addr(ip);
 
	if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr)) < 0)
	{
		perror("Fail to bind");
		exit(EXIT_FAILURE);
	}
	
	listen(sockfd,5);
	printf("listen....\n");
	return sockfd;
}
 
//数据库中手动创建2个表:user_table,word_table
int main(int argc, char *argv[])
{
	int pid;	
	sqlite3 *pdb;
	int listenfd,connect_fd;
	int addr_len = sizeof(struct sockaddr);
	struct sockaddr_in peer_addr;
 
	if(argc < 4)
	{
		fprintf(stderr,"Usage : %s ip port system.db.\n",argv[0]);
		exit(EXIT_FAILURE);
	}
 
	//探测子进程的改变状态,回收僵尸态子进程
	if(signal(SIGCHLD,signal_handler) == SIG_ERR)
	{
		perror("Fail to signal");
		exit(EXIT_FAILURE);
	}
 
	if(sqlite3_open(argv[3],&pdb) != SQLITE_OK)
	{
		fprintf(stderr,"sqlite3 open %s : %s.\n",argv[3],sqlite3_errmsg(pdb));
		exit(EXIT_FAILURE);
	}
 
	//初始化tcp连接,得到监听套接字
	listenfd = init_tcp(argv[1],argv[2]);
 
	//提取客户段的链接请求,创建子进程和客户端交互
	while(1)
	{
		if((connect_fd = accept(listenfd,(struct sockaddr *)&peer_addr,&addr_len)) < 0)
		{
			perror("Fail to accept");
			exit(EXIT_FAILURE);
		}
		
		if((pid = fork()) < 0)
		{
			perror("Fail to fork");
			exit(EXIT_FAILURE);
		}
 
		//创建子进程处理客户端的请求
		if(pid == 0){
			close(listenfd);
			do_client(connect_fd,pdb);
		}
		close(connect_fd);
	}
 
	exit(EXIT_SUCCESS);
}
#include "head.h" 
 
int do_register(int sockfd,sqlite3 *pdb,char *_username,char *_password)
{
	char *errmsg;
	char buf[1024];
	char **dbresult;
	int nrow = 0,ncolumn = 0;
	char sql[1024] = {0};
	mhead_t *head = (mhead_t *)buf;	
 
	sprintf(sql,"select * from user_table where NAME='%s';",_username);
	if(sqlite3_get_table(pdb,sql,&dbresult,&nrow,&ncolumn,&errmsg) != 0)
	{
		fprintf(stderr,"sqlite3 get table error : %s.\n",errmsg);
		exit(EXIT_FAILURE);
	}
 
	//没有这样的用户名
	if(nrow == 0)
	{
		//录入数据库
		bzero(sql,sizeof(sql));
		sprintf(sql,"insert into user_table values('%s','%s');",_username,_password);
		EXEC_SQL(pdb,sql,errmsg);
		
		printf("ok ........\n");
 
		head->type = USER_SUCCESS;
		if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
		{
			perror("Fail to send");
			exit(EXIT_FAILURE);
		}
	//注册失败,用户名存在
	}else{
		head->type = USER_FAILURE;
		if(send(sockfd,buf,sizeof(mhead_t),0) < 0)
		{
			perror("Fail to send");
			exit(EXIT_FAILURE);
		}
		//表示未知
		printf("???????\n");
	}
	//插入到数据库之后,释放dbresult结果
	sqlite3_free_table(dbresult);
	return 0;
}
 
int do_login(int sockfd,sqlite3 *pdb,char *_username,char *_password)
{  
	char *errmsg;
	int i,j;
	char buf[1024];
	char **dbresult;
	int nrow = 0,ncolumn = 0;
	char sql[1024] = {0};
	mhead_t *head = (mhead_t *)buf;	
	char *zsql="select * from user_table";
	int index=0;
    //查找数据库中是否有该帐号
   //	sprintf(sql,"select * from user_table where NAME='%s';",_username);
	if(sqlite3_get_table(pdb,zsql,&dbresult,&nrow,&ncolumn,&errmsg) != 0)
	{
		fprintf(stderr,"sqlite3 get table error : %s.\n",errmsg);
		exit(EXIT_FAILURE);
	}
	//登陆
	for(i=0;i<=nrow;i++)
	{
	 for(j=0;j<ncolumn;j++)
	 {
	  if(strcmp(dbresult[index],_username)==0&&strcmp(dbresult[index+1],_password)==0)
	  {
	   printf("登陆成功\n");
	   head->type=USER_SUCCESS;
	   printf("%d\n",head->type);
	   if(send(sockfd,buf,sizeof(mhead_t),0)<0)
	   {
	    perror("Fail to send");
		exit(EXIT_FAILURE);
	   }
	   sqlite3_free_table(dbresult);
	   return 0;
	  }
	 }
	 index++;
	}
	//帐号密码错误
	head->type=USER_FAILURE;
	if(send(sockfd,buf,sizeof(mhead_t),0)<0)
	{
	   perror("Fail to send");
	   exit(EXIT_FAILURE);
	}
	printf("??????\n");
	sqlite3_free_table(dbresult);
	return 0;
}
int do_word(int sockfd,sqlite3 *pdb,char *_word)
{
	char *errmsg;
	int i,j;
	char buf[1024];
	char **dbresult;
	int nrow = 0,ncolumn = 0;
	char sql[1024] = {0};
	char *zsql="select * from dict_table";
	int index;
	mhead_t *head = (mhead_t *)buf;	
    //查找数据库中是否有该单词
	//sprintf(sql,"select * from dict_table where word='%s';",_word);
	if(sqlite3_get_table(pdb,zsql,&dbresult,&nrow,&ncolumn,&errmsg) != 0)
	{
		fprintf(stderr,"sqlite3 get table error : %s.\n",errmsg);
		exit(EXIT_FAILURE);
	}
    for(i=0;i<=nrow;i++)
	{
	  for(j=0;j<ncolumn;j++)
	  {
	   if(strcmp(dbresult[index],_word)==0)
	   {
	    //查单词
		printf("ok\n");
		head->type=USER_SUCCESS;
		strcpy(head->word,dbresult[index+1]);
		if(send(sockfd,buf,sizeof(mhead_t),0)<0)
		{
			perror("Fail to send");
			exit(EXIT_FAILURE);
		}
		printf("%d\n",index);
		sqlite3_free_table(dbresult);
		return 0;
	   }
	   index++;
	  }
	}
	//查找失败,没有该单词
	head->type=USER_FAILURE;
	if(send(sockfd,buf,sizeof(mhead_t),0)<0)
	{
	  perror("Fail to send");
	  exit(EXIT_FAILURE);
	}
	printf("?????\n");
	sqlite3_free_table(dbresult);
	return 0;
}
int do_client(int sockfd,sqlite3 *pdb)
{
	int n;
	int count = 0;
	char buf[1024];
	mhead_t *head = (mhead_t *)buf;	
 
	while(1)
	{
		count = 0;
		//接收协议头
		while(1)
		{
			n = recv(sockfd,buf + count,sizeof(mhead_t) - count,0);
			if(n <= 0){
				exit(EXIT_FAILURE);
			}
 
			count += n;
			printf("count : %d mhead_t : %ld\n",count,sizeof(mhead_t));
			if(count == sizeof(mhead_t))
				break;
		}
 
		switch(head->type)
		{
		case USER_REGISTER:
			do_register(sockfd,pdb,head->username,head->password);	
			break;
		
		case USER_LOGIN:
			do_login(sockfd,pdb,head->username,head->password);
			break;
		case USER_WORD:
			do_word(sockfd,pdb,head->word);
			break;
		defalut:
			exit(EXIT_SUCCESS);
		}	
	}
 
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/52198.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Xamarin.Android实现加载中的效果

目录 1、说明2、代码如下2.1 图1的代码2.1.1、创建一个Activity或者Fragment&#xff0c;如下&#xff1a;2.1.2、创建Layout2.1.3、如何使用 2.2 图2的代码 4、其他补充4.1 C#与Java中的匿名类4.2 、其他知识点 5、参考资料 1、说明 在实际使用过程中&#xff0c;常常会用到点…

python和c加加有什么区别,c和c++和python先学哪个

本篇文章给大家谈谈c加加编程和python编程有什么区别&#xff0c;以及python和c加加有什么区别&#xff0c;希望对各位有所帮助&#xff0c;不要忘了收藏本站喔。 1、python和c学哪个好 学C好。 C通常比Python更快&#xff0c;因为C是一种编译型语言&#xff0c;而Python则是…

批量插入数据、MVC三层分离

八、批量插入数据 1、使用Statement&#xff08;&#xff09; 2、使用PreparedStatement() 3、使用批量操作API 4、优化 九、MVC三层分离

JDBC Some Templates

JDBCTemplate 是Spring对JDBC的封装&#xff0c;使用JDBCTemplate方便实现对数据的操作。 <!-- orm:Object relationship mapping m对象 关系 映射-->引入依赖 <!-- 基于Maven依赖的传递性&#xff0c;导入spring-content依赖即可导入当前所需的所有…

Java语言跨平台执行的核心JVM

本文重点 在前面的课程中,我们介绍了java中的三层JDK->JRE->JVM,其中JVM称为Java的虚拟机,只是用来执行的,JRE是运行环境,要想在操作系统中运行,除了JVM还需要类库,JDK=JRE+开发的包和工具。本文就将介绍一下JVM究竟为何物? JVM 有的人会认为JVM是java中的东西…

【业务功能篇59】Springboot + Spring Security 权限管理 【下篇】

UserDetails接口定义了以下方法&#xff1a; getAuthorities(): 返回用户被授予的权限集合。这个方法返回的是一个集合类型&#xff0c;其中每个元素都是一个GrantedAuthority对象&#xff0c;表示用户被授予的权限。getPassword(): 返回用户的密码。这个方法返回的是一个字符…

❤️创意网页:炫酷的网页 - 创造华丽粒子动画

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;简单好用又好看&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;欢迎踏入…

【雕爷学编程】MicroPython动手做(19)——掌控板之蜂鸣器与音乐2

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

IntelliJ IDEA 2023.2 新版本,拥抱 AI

IntelliJ IDEA 近期连续发布多个EAP版本&#xff0c;官方在对用户体验不断优化的同时&#xff0c;也新增了一些不错的功能&#xff0c;尤其是人工智能助手补充&#xff0c;AI Assistant&#xff0c;相信在后续IDEA使用中&#xff0c;会对开发者工作效率带来不错的提升。 以下是…

eda、gnm、anm究竟是个啥?

安装prody pip install prody -i https://pypi.tuna.tsinghua.edu.cn/simpleeda、anm、gnm eda(essential dynamics analysis) 另一个名字PCA(Principal Component Analysis) 或 NMA(Normal Mode Analysis)。 eda分析可以帮助人们理解生物大分子基本的运动模式和构象变化。…

211. 添加与搜索单词 - 数据结构设计---------------字典树

211. 添加与搜索单词 - 数据结构设计 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a; 原题链接&#xff1a; 211. 添加与搜索单词 - 数据结构设计 https://leetcode.cn/problems/design-add-and-search-words-data-structure/descriptio…

平板光波导中导模的(注意不是泄露模)传播常数β的matlab计算(验证了是对的)

参照的是导波光学_王建(清华大学)的公式(3-1-2、3-1-3)&#xff0c;算的参数是这本书的图3-3的。 function []PropagationConstantsMain() clear;clc;close all lambda01.55;%真空或空气中的入射波长&#xff0c;单位um k02*pi/lambda0; m3;%导模阶数(需要人为指定) n11.62;%芯…

【Qt】利用Tool Button控件创建下拉菜单按钮

功能描述 利用qt进行界面设计和开发&#xff0c;创建下拉按钮。 详细实现 1、在qt侧工具栏利用设计打开.ui文件 2、创建按钮 创建一个Tool Button按钮&#xff0c;并在属性窗口中的QToolButton栏中选中MenuButtonPopup属性。 3、创建action 在Action编辑器创建对应的ac…

HTML不常用但是好用的标签

sub sup <p>这个文本包含 <sub>111</sub>文本。</p> <p>这个文本包含 <sup>上标</sup> 文本。</p>下标文本将会显示在当前文本流中字符高度的一半为基准线的下方&#xff0c;但是与当前文本流中文字的字体和字号都是一样的。…

科技项目验收测试:验证软件产品功能与性能的有效手段

科技项目验收测试是验证软件产品功能与性能的重要手段&#xff0c;在项目开发中起到了至关重要的作用。本文将从产品质量、需求验证、性能测试等方面&#xff0c;探讨科技项目验收测试的有效手段。 1、产品质量保证是验收测试的核心 科技项目验收测试的核心目标是验证软件产品…

Linux CentOS监控系统的运行情况工具 - top/htop/glances/sar/nmon

在CentOS系统中&#xff0c;您可以使用以下工具来监控系统的运行情况&#xff1a; 1. top&#xff1a; top 是一个命令行工具&#xff0c;用于实时监控系统的进程、CPU、内存和负载情况。您可以使用以下命令来启动 top&#xff1a; top 输出 2. htop&#xff1a; htop 是一…

github token使用方法

git remote set-url origin https://<githubtoken>github.com/<username>/<repositoryname>.git 在私有仓库的HTTPS的url上加入<githubtoken>即为token url&#xff0c;可以免ssh key登录

SpringBoot读取配置文件顺序

文章目录 一、前言二、SpringBoot配置文件目录读取顺序源码解析 三、SpringBoot配置文件类型读取顺序源码解析 一、前言 本文通过源码分析 SpringBoot 加载配置文件目录的顺序&#xff0c;以及 properties、xml、yml、yaml文件的读取顺序 二、SpringBoot配置文件目录读取顺序…

传统计算机视觉

传统计算机视觉 计算机视觉难点图像分割基于主动轮廓的图像分割基于水平集的图像分割交互式图像分割基于模型的运动分割 目标跟踪基于光流的点目标跟踪基于均值漂移的块目标跟踪基于粒子滤波的目标跟踪基于核相关滤波的目标跟踪 目标检测一般目标检测识别之特征一般目标检测识别…

绕过TLS/akamai指纹护盾

文章目录 前言TLS指纹什么是TLS指纹测试TLS指纹绕过TLS指纹使用原生urllib使用其他成熟库&#xff01;&#xff01;修改requests底层代码 Akamai指纹相关&#xff08;HTTP/2指纹&#xff09;什么是Akamai指纹测试Akamai指纹绕过Akamai指纹使用其他成熟库 实操参考 前言 有道是…