2018-2019 1 20165203 实验五 通用协议设计

2018-2019 1 20165203 实验五 通用协议设计

OpenSSL学习

  • 定义:OpenSSL是为网络通信提供安全及数据完整性的一种安全协议,囊括了主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供了丰富的应用程序供测试或其它目的使用。
  • 基本功能:
    • 密码算法库
    • SSL协议库
    • 应用程序
  • 其中:密码算法库是一个强大完整的密码算法库,它是OpenSSL的基础部分,也是很值得一般密码安全技术人员研究的部分,它实现了目前大部分主流的密码算法和标准。主要包括对称算法、非对称算法、散列算法、数字签名和认证、X509数字证书标准、PKCS12、PKCS7等标准。其他两个功能部分SSL协议和应用程序都是基于这个库开发的。
  • 在密码算法库的基础上实现的,SSL协议部分完全实现和封装了SSL协议的三个版本和TLS协议。使用协议库,完全可以建立一个SSL服务器和SSL客户端。
  • 应用程序是基于密码算法库和SSL协议库实现的命令,熟悉OpenSSL可以从使用这些应用程序开始。应用程序覆盖了密码技术的应用,主要包括了各种算法的加密程序和各种类型密钥的产生程序(如RSA、Md5、Enc等等)、证书签发和验证程序(如Ca、X509、Crl等)、SSL连接测试程序(如S_client和S_server等)以及其它的标准应用程序(如Pkcs12和Smime等)。

任务一

两人一组
基于Socket实现TCP通信,一人实现服务器,一人实现客户端
研究OpenSSL算法,测试对称算法中的AES,非对称算法中的RSA,Hash算法中的MD5
选用合适的算法,基于混合密码系统实现对TCP通信进行机密性、完整性保护。
学有余力者,对系统进行安全性分析和改进。  
  • 实验步骤:
    1.安装Openssl。
  • 在虚拟机的Linux系统中前往Openssl官网,下载openssl-master.zip
  • 下载完毕后,利用unzip openssl-master.zip命令解压,解压后如图所示。

1297630-20181216123643799-934363737.jpg

  • 利用如下命令进行安装。
$ ./config
$ make
$ make test
$ make install  
  • 安装完毕即可。

2.进行安装测试。

  • 编写一个测试代码test_openssl.c
#include <stdio.h>
#include <openssl/evp.h>int main(){OpenSSL_add_all_algorithms();return 0;
}  
  • 使用命令gcc -o test_openssl test_openssl.c -L/usr/local/ssl/lib -lcrypto -ldl -lpthread进行编译,生成“test_openssl”可执行文件,运行。接下来,执行echo $?,打印出的结果是0,则代表运行成功。
    1297630-20181216123716759-1833797132.jpg

  • 命令的学习:

-L选项——指定链接库的文件夹地址;
-lcrypto——导入OpenSSL所需包;
-ldl选项——加载动态库;
-lpthread选项——链接POSIX thread库    

3.基于Socket实现TCP通信,实现服务器和客户端的通信。连接后,如图所示。

1297630-20181216123744957-1344884340.jpg

4.选用合适的算法,基于混合密码系统实现对TCP通信进行机密性、完整性保护。

  • AES

编写代码aes.c


#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/aes.h>
#pragma comment(lib,"libeay32.lib")
int main(int argc, char **argv)
{unsigned char buf[512];unsigned char buf2[512];unsigned char buf3[512];unsigned char aes_keybuf[32];memset(buf,1,sizeof(buf));    memset(buf,0,sizeof(buf2));    memset(buf,0,sizeof(buf3));memset(aes_keybuf,0,sizeof(aes_keybuf));AES_KEY aeskey;AES_set_encrypt_key(aes_keybuf,256,&aeskey);for(int i=0;i<sizeof(buf);i+=16)AES_encrypt(buf+i,buf2+i,&aeskey);AES_set_decrypt_key(aes_keybuf,256,&aeskey);for(int i=0;i<sizeof(buf);i+=16)AES_decrypt(buf2+i,buf3+i,&aeskey);if(memcmp(buf,buf3,sizeof(buf))==0)printf("test success\r\n");elseprintf("test fail\r\n");
}  

使用gcc aes.c -o aes -L/usr/local/ssl/lib -lcrypto -ldl -lpthread进行编译,并运行,运行完结果如图所示。

1297630-20181216124001900-1498790812.jpg

  • RSA算法

编写rsa.c


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<openssl/rsa.h>
#include<openssl/pem.h>
#include<openssl/err.h>
#define OPENSSLKEY "test.key"
#define PUBLICKEY "test_pub.key"
#define BUFFSIZE 1024
char* my_encrypt(char *str,char *path_key);//加密
char* my_decrypt(char *str,char *path_key);//解密
int main(void){char *source="I'm 20165203xyx who is a nice student.";char *ptr_en,*ptr_de;printf("source is    :%s\n",source);ptr_en=my_encrypt(source,PUBLICKEY);printf("after encrypt:%s\n",ptr_en);ptr_de=my_decrypt(ptr_en,OPENSSLKEY);printf("after decrypt:%s\n",ptr_de);if(ptr_en!=NULL){free(ptr_en);}   if(ptr_de!=NULL){free(ptr_de);}   return 0;
}
char *my_encrypt(char *str,char *path_key){char *p_en;RSA *p_rsa;FILE *file;int flen,rsa_len;if((file=fopen(path_key,"r"))==NULL){perror("open key file error");return NULL;    }   if((p_rsa=PEM_read_RSA_PUBKEY(file,NULL,NULL,NULL))==NULL){ERR_print_errors_fp(stdout);return NULL;}   flen=strlen(str);rsa_len=RSA_size(p_rsa);p_en=(unsigned char *)malloc(rsa_len+1);memset(p_en,0,rsa_len+1);if(RSA_public_encrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_en,p_rsa,RSA_NO_PADDING)<0){return NULL;}RSA_free(p_rsa);fclose(file);return p_en;
}
char *my_decrypt(char *str,char *path_key){char *p_de;RSA *p_rsa;FILE *file;int rsa_len;if((file=fopen(path_key,"r"))==NULL){perror("open key file error");return NULL;}if((p_rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))==NULL){ERR_print_errors_fp(stdout);return NULL;}rsa_len=RSA_size(p_rsa);p_de=(unsigned char *)malloc(rsa_len+1);memset(p_de,0,rsa_len+1);if(RSA_private_decrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_de,p_rsa,RSA_NO_PADDING)<0){return NULL;}RSA_free(p_rsa);fclose(file);return p_de;
}  

同样的方法编译运行,得到结果,成功。

  • MD5算法。
#define _GNU_SOURCE#include <stdio.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <ctype.h>#include "openssl/md5.h"MD5_CTX  md5_ctx;
static int MD5mod(const char* str, int length, int mod){char sign[16] = {0};MD5_Init(&md5_ctx);MD5_Update(&md5_ctx, str, length);MD5_Final(sign, &md5_ctx);printf("digest:%s\n",sign);int sum = 0;for (int i=0; i < 16; i ++) {sum += (sign[i]&0xff);}int offset = sum % mod;return offset;}int main(int argc, char** argv){if( argc < 4){fprintf(stderr, "%s num infile outfile\n", argv[0]);exit(-1);}int num = atoi(argv[1]) ;if( num <= 0){fprintf(stderr, "ERROR: num error: %s\n", argv[1]);exit(-1);}FILE* in = fopen(argv[2], "r");if( in == NULL){perror("fopen");fprintf(stderr, "ERROR: infile error: %s\n", argv[2]);exit(-1);}FILE** OUT = (FILE**)malloc(sizeof(FILE*) * num);for(int i=0; i<num; ++i){char buf[256] = {0};sprintf(buf, "%s_%d", argv[3], i);OUT[i] = fopen(buf, "w");if( OUT[i] == NULL){perror("fopen");fprintf(stderr, "ERROR: infile error: %s\n", argv[2]);exit(-1);}}size_t len = 0;ssize_t read;char * line = NULL;while ((read = getline(&line, &len, in)) != -1) {int  klen = 0;while( klen < read ){if( isspace( *(line+klen)) ) break;klen++;}//   char id[256]={0};//   strncpy(id, line, klen);//   printf("id=%s\tklen=%d\tread=%ld\tline=%s", id, klen, read, line);fprintf(OUT[MD5mod(line, klen, num)], "%s", line);}if(line) free(line);return 0;
}  

编译运行,如图所示。

1297630-20181216124034999-330290801.jpg

任务二

在Ubuntu中实现对实验二中的“wc服务器”通过混合密码系统进行防护
提交测试截图  
  1. 学习wc服务器模式如下。

1297630-20181216124059502-331994892.png

  1. 编写代码如下。

server.c

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>#include <openssl/evp.h>#define MAXBUF 1024int main(int argc, char **argv)
{int sockfd, new_fd;socklen_t len;struct sockaddr_in my_addr, their_addr;unsigned int myport, lisnum;char buf[MAXBUF + 1];SSL_CTX *ctx;if (argv[1])myport = atoi(argv[1]);elsemyport = 5227;if (argv[2])lisnum = atoi(argv[2]);elselisnum = 2;/* SSL 库初始化 */SSL_library_init();/* 载入所有 SSL 算法 */OpenSSL_add_all_algorithms();/* 载入所有 SSL 错误消息 */SSL_load_error_strings();/* 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text */ctx = SSL_CTX_new(SSLv23_server_method());/* 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准 */if (ctx == NULL) {ERR_print_errors_fp(stdout);exit(1);}/* 载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 */if (SSL_CTX_use_certificate_file(ctx, argv[3], SSL_FILETYPE_PEM) <= 0) {ERR_print_errors_fp(stdout);exit(1);}/* 载入用户私钥 */if (SSL_CTX_use_PrivateKey_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0){ERR_print_errors_fp(stdout);exit(1);}/* 检查用户私钥是否正确 */if (!SSL_CTX_check_private_key(ctx)) {ERR_print_errors_fp(stdout);exit(1);}/* 开启一个 socket 监听 */if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {perror("socket");exit(1);} elseprintf("socket created\n");bzero(&my_addr, sizeof(my_addr));my_addr.sin_family = PF_INET;my_addr.sin_port = htons(myport);my_addr.sin_addr.s_addr = INADDR_ANY;if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))== -1) {perror("bind");exit(1);} elseprintf("binded\n");if (listen(sockfd, lisnum) == -1) {perror("listen");exit(1);} elseprintf("begin listen\n");while (1) {SSL *ssl;len = sizeof(struct sockaddr);/* 等待客户端连上来 */if ((new_fd =accept(sockfd, (struct sockaddr *) &their_addr,&len)) == -1) {perror("accept");exit(errno);} elseprintf("server: got connection from %s, port %d, socket %d\n",inet_ntoa(their_addr.sin_addr),ntohs(their_addr.sin_port), new_fd);/* 基于 ctx 产生一个新的 SSL */ssl = SSL_new(ctx);/* 将连接用户的 socket 加入到 SSL */SSL_set_fd(ssl, new_fd);/* 建立 SSL 连接 */if (SSL_accept(ssl) == -1) {perror("accept");close(new_fd);break;}/* 开始处理每个新连接上的数据收发 */bzero(buf, MAXBUF + 1);strcpy(buf, "hello");/* 发消息给客户端 */len = SSL_write(ssl, buf, strlen(buf));if (len <= 0) {printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",buf, errno, strerror(errno));goto finish;} elseprintf("消息'%s'发送成功,共发送了%d个字节!\n",buf, len);bzero(buf, MAXBUF + 1);/* 接收客户端的消息 */len = SSL_read(ssl, buf, MAXBUF);if (len > 0)printf("接收消息成功:'%s',共%d个字节的数据\n",buf, len);elseprintf("消息接收失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno));/* 处理每个新连接上的数据收发结束 */finish:/* 关闭 SSL 连接 */SSL_shutdown(ssl);/* 释放 SSL */SSL_free(ssl);/* 关闭 socket */close(new_fd);}/* 关闭监听的 socket */close(sockfd);/* 释放 CTX */SSL_CTX_free(ctx);return 0;
}  

talent.c

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>#include <openssl/evp.h>#define MAXBUF 1024int main(int argc, char **argv)
{int sockfd, new_fd;socklen_t len;struct sockaddr_in my_addr, their_addr;unsigned int myport, lisnum;char buf[MAXBUF + 1];SSL_CTX *ctx;if (argv[1])myport = atoi(argv[1]);elsemyport = 5227;if (argv[2])lisnum = atoi(argv[2]);elselisnum = 2;/* SSL 库初始化 */SSL_library_init();/* 载入所有 SSL 算法 */OpenSSL_add_all_algorithms();/* 载入所有 SSL 错误消息 */SSL_load_error_strings();/* 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text */ctx = SSL_CTX_new(SSLv23_server_method());/* 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准 */if (ctx == NULL) {ERR_print_errors_fp(stdout);exit(1);}/* 载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 */if (SSL_CTX_use_certificate_file(ctx, argv[3], SSL_FILETYPE_PEM) <= 0) {ERR_print_errors_fp(stdout);exit(1);}/* 载入用户私钥 */if (SSL_CTX_use_PrivateKey_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0){ERR_print_errors_fp(stdout);exit(1);}/* 检查用户私钥是否正确 */if (!SSL_CTX_check_private_key(ctx)) {ERR_print_errors_fp(stdout);exit(1);}/* 开启一个 socket 监听 */if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {perror("socket");exit(1);} elseprintf("socket created\n");bzero(&my_addr, sizeof(my_addr));my_addr.sin_family = PF_INET;my_addr.sin_port = htons(myport);my_addr.sin_addr.s_addr = INADDR_ANY;if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))== -1) {perror("bind");exit(1);} elseprintf("binded\n");if (listen(sockfd, lisnum) == -1) {perror("listen");exit(1);} elseprintf("begin listen\n");while (1) {SSL *ssl;len = sizeof(struct sockaddr);/* 等待客户端连上来 */if ((new_fd =accept(sockfd, (struct sockaddr *) &their_addr,&len)) == -1) {perror("accept");exit(errno);} elseprintf("server: got connection from %s, port %d, socket %d\n",inet_ntoa(their_addr.sin_addr),ntohs(their_addr.sin_port), new_fd);/* 基于 ctx 产生一个新的 SSL */ssl = SSL_new(ctx);/* 将连接用户的 socket 加入到 SSL */SSL_set_fd(ssl, new_fd);/* 建立 SSL 连接 */if (SSL_accept(ssl) == -1) {perror("accept");close(new_fd);break;}/* 开始处理每个新连接上的数据收发 */bzero(buf, MAXBUF + 1);strcpy(buf, "hello");/* 发消息给客户端 */len = SSL_write(ssl, buf, strlen(buf));if (len <= 0) {printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",buf, errno, strerror(errno));goto finish;} elseprintf("消息'%s'发送成功,共发送了%d个字节!\n",buf, len);bzero(buf, MAXBUF + 1);/* 接收客户端的消息 */len = SSL_read(ssl, buf, MAXBUF);if (len > 0)printf("接收消息成功:'%s',共%d个字节的数据\n",buf, len);elseprintf("消息接收失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno));/* 处理每个新连接上的数据收发结束 */finish:/* 关闭 SSL 连接 */SSL_shutdown(ssl);/* 释放 SSL */SSL_free(ssl);/* 关闭 socket */close(new_fd);}/* 关闭监听的 socket */close(sockfd);/* 释放 CTX */SSL_CTX_free(ctx);return 0;
}  
  1. 编译运行。
  • 使用gcc -o server server.c -I /usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl -lpthread编译server.c
  • 使用gcc -o telent telent.c -I /usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl -lpthread
  • 使用openssl genrsa -out privkey.pem 1024 openssl req -new -x509 -key privkey.pem -out CAcert.pem -days 1095来生产私钥和证书。
  • 使用./server 5203 1 CAcert.pem privkey.pem ./telent 127.0.0.1 5203来运行。

运行后如图所示。

1297630-20181216124143645-1449725082.jpg

实验中出现的问题及解答。

Q1:安装openssl时出现如图所示问题。

1297630-20181216124248551-55755620.jpg

A1:将“openssl-master”文件夹下的“libcrypto.a”“libssl.a”放在/usr/local/ssl/lib目录下(注意使用sudo权限),编译时链接这个目录即可。

Q2:编译任务2时出现如图所示问题。

1297630-20181216124322655-1296351604.jpg

A2:要使用命令gcc -o server server.c -I /usr/local/ssl/include -L/usr/local/ssl/lib -lssl -lcrypto -ldl -lpthread来进行相应的库链接。

实验感想

本次实验我们主要学习了Openssl的主要内容结构和用法,该实验还与计算机网络和密码学的相关知识结合起来,更符合我们信息安全专业的特点,也学到了很多知识。
本学期该课的实验就要结束了,但是学习知识的脚步要永远进行着,生命不息,学习不止,只有不断学习新知识才会一直进步。

转载于:https://www.cnblogs.com/20165203-xyx/p/10126214.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

弄懂webpack,只要看这一片就够了(文末有福利)

什么是webpack ​ webpack是什么&#xff0c;官网中是这么说的。 ​ 本质上&#xff0c;webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时&#xff0c;它会递归地构建一个依赖关系图(dependency graph)&#xff0c;其中包…

beta冲刺总结那周余嘉熊掌将得队

作业格式 课程名称&#xff1a;软件工程1916|W&#xff08;福州大学&#xff09;作业要求&#xff1a;项目Beta冲刺团队名称&#xff1a; 那周余嘉熊掌将得队作业目标&#xff1a;beta冲刺总结队员学号队员姓名博客地址备注221600131Jaminhttps://www.cnblogs.com/JaminWu/队长…

在Winform中菜单动态添加“最近使用文件”

最近在做文件处理系统中&#xff0c;要把最近打开文件显示出来&#xff0c;方便用户使用。网上资料有说&#xff0c;去遍历“C:\Documents and Settings\Administrator\Recent”下的最近文档本。文主要介绍在Winform界面菜单中实现【最近使用的文件】动态菜单的处理&#xff0c…

Vue组件通信原理剖析(一)事件总线的基石 $on和$emit

首先我们先从一个面试题入手。 面试官问&#xff1a; “Vue中组件通信的常用方式有哪些&#xff1f;” 我答&#xff1a; 1. props 2. 自定义事件 3. eventbus 4. vuex 5. 还有常见的边界情况$parent、$children、$root、$refs、provide/inject 6. 此外还有一些非props特性$att…

display:flex弹性布局

一、背景 前段时间帮公司运维小姑娘调整她自己写的页面样式时发现她用了display: flex&#xff0c;我这个后端老古董还不太懂flex&#xff0c;自愧不如啊&#xff0c;所以写篇博客记录学习下。 现在写的前端页面还停留在依赖 display 属性 position属性 float属性的布局方式&…

Vue组件通信原理剖析(二)全局状态管理Vuex

首先我们先从一个面试题入手。 面试官问&#xff1a; “Vue中组件通信的常用方式有哪些&#xff1f;” 我答&#xff1a; 1. props 2. 自定义事件 3. eventbus 4. vuex 5. 还有常见的边界情况$parent、$children、$root、$refs、provide/inject 6. 此外还有一些非props特性$att…

初识单点登录及JWT实现

单点登录 多系统&#xff0c;单一位置登录&#xff0c;实现多系统同时登录的一种技术 &#xff08;三方登录&#xff1a;某系统使用其他系统的用户&#xff0c;实现本系统登录的方式。如微信登录、支付宝登录&#xff09; 单点登录一般是用于互相授信的系统&#xff0c;实现单一…

Vue组件通信原理剖析(三)provide/inject原理分析

首先我们先从一个面试题入手。 面试官问&#xff1a; “Vue中组件通信的常用方式有哪些&#xff1f;” 我答&#xff1a; 1. props 2. 自定义事件 3. eventbus 4. vuex 5. 还有常见的边界情况$parent、$children、$root、$refs、provide/inject 6. 此外还有一些非props特性$att…

iMX6开发板-uboot-网络设置和测试

本文章基于迅为IMX6开发板 将iMX6开发板通过网线连接到路由器&#xff0c;同时连接好调试串口&#xff0c;上电立即按 enter&#xff0c;即可进入 uboot。然后输入命令 pri&#xff0c;查看开发板当前的配置&#xff0c;如下图所示可以看到 ip 地址、子网掩码 等信息。 本文档测…

Django ajax 检测用户名是否已被注册

添加一个 register.html 页面 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <form><p>用户名<input id"username" type&…

详解JDBC连接数据库

一、概念 1. 为了能让程序操作数据库&#xff0c;对数据库中的表进行操作&#xff0c;每一种数据库都会提供一套连接和操作该数据库的驱动&#xff0c;而且每种数据库的驱动都各不相同&#xff0c;例如mysql数据库使用mysql驱动&#xff0c;oracle数据库使用oracle驱动&#xf…

ZOJ4024 Peak

题意 给出一个数组 判断这个数组是否形成了一个“山峰” 即中间有个数最大 从第一个数到这个数递增 从这个数到最后一个数递减 模拟 从两端分别以递增和递减判断 看第一个不满足递增或递减的数是否相等并且没越界就可以了 AC代码&#xff1a; 1 #include<bits/stdc.h>2 u…

springmvc跨域问题

1、跨域问题&#xff1a; 按照网上所有的方法试了一遍&#xff0c;都没跨过去&#xff0c;正在无助之际&#xff0c;使用filter按照下面的方法解决的时候出现了转机&#xff1a; 添加filter&#xff1a; package com.thc.bpm.filter;import javax.servlet.*; import javax.serv…

成功秀了一波scala spark ML逻辑斯蒂回归

1、直接上官方代码&#xff0c;调整过的&#xff0c;方可使用 package com.test import org.apache.spark.{SparkConf, SparkContext} import org.apache.spark.mllib.classification.{LogisticRegressionModel, LogisticRegressionWithLBFGS} import org.apache.spark.mllib.e…

nodeJS中的异步编程

nodejs 不是单线程 在博客项目中关于异步问题&#xff1a; 1.当用户添加一条博客时 需要通过post方式向服务器发送数据 后台获取用户以post方式拿到传送过来的数据 然后存入数据库&#xff1a; 上面的代码&#xff1a;创建一个空字符串 当用户向服务器发送请求时出发data事件将…

nodeJs 操作数据库

首先在node中下载mysql包 npm install mysql 连接数据库 var mysql require(mysql); var con mysql.createConnection({host : localhost,user : root,password : root,database : blog });开启链接 con.connect();执行增删改查 不同功能创建不同的sql语句即可…

总结面试题——Javascript

文章目录1.闭包2.作用域链3.JavaScript的原型 原型链 有什么特点4.事件代理5.Javascript如何实现继承6.this对象7.事件模型8.new操作符9.ajax原理10.解决跨域问题11.模块化开发怎么做12.异步加载js的方式有哪些13.会造成内存泄漏的操作14.XML和JSON的区别15.webpack16.AMD和Com…

OAuth2.0 知多少

OAuth2.0 知多少 原文:OAuth2.0 知多少1. 引言 周末逛简书&#xff0c;看了一篇写的极好的文章&#xff0c;点击大红心点赞&#xff0c;就直接给我跳转到登录界面了&#xff0c;原来点赞是需要登录的。 可是没有我并没有简书账号&#xff0c;一直使用的QQ的集成登录。下面有一排…

五分钟带你摸透 Vue组件及组件通讯

一.组件化开发 组件 (Component) 是 Vue.js 强大的功能之一。组件可以扩展 HTML 元素&#xff0c;封装可重用的代 码。在较高层面上&#xff0c;组件是自定义元素&#xff0c;Vue.js 的编译器为它添加特殊功能。在vue中都是组件化开发的&#xff0c;组件化开发就是把一个完整的…

微信公众号开发-接入

一 首先实现内网穿透&#xff0c;公众号需要连接我们的服务器&#xff0c;内外无法访问&#xff0c;所以先实现自己的内网可以测试时连接外网&#xff0c;下载natapp&#xff0c;选择windows&#xff0c;顺便下载config,ini 配置文件。注册好购买免费的隧道 然后将token写入配置…