加泰罗尼亚的议会,推翻了数百年前的判决,当时将数百无辜女性当作女巫。
15世纪到18世纪,就是半个世纪之前,中国还在窦娥冤六月雪,袁崇焕被凌迟的年代。
我很好奇,现在人大会为袁将军平反吗?
加泰罗尼亚的议会,推翻了数百年前的判决,当时将数百无辜女性当作女巫。
15世纪到18世纪,就是半个世纪之前,中国还在窦娥冤六月雪,袁崇焕被凌迟的年代。
我很好奇,现在人大会为袁将军平反吗?
举例说明,是一种关照。我们遇到一种新的情况,比如新技术、新商业模式,总会希望讲述者以更通俗易懂的方式向我们介绍,其中最常用的方法是举例说明,或者打个比方。
我越来越发现,举例说明看起来是对听众的关照,其实也是一种深深的蔑视,是对大家理解能力的深深的不信任,预设了面前的人群,不具备理解即将展开的话题的讨论资格与能力,因为你没有贝叶斯知识,所以只能向你举例说明不完备问题。
更有意思的是,讲述者有时候也仅仅把自己对真实的理解,停留在举例说明的层次,这时候与其说是一种蔑视,更多不过是有意无意的自我欺骗罢了。
年纪大了,学习进度非常慢,但学习感悟非常多。
每天在playground上做题,再晚都会争取完成。但是一个简单的loop或者if else,都会耗时许久。
前几周刚刚学会了right hand rules,就是解maze问题时常用的一种方法,伪代码如下:
if isBlockRight {
moveForward()
} else {
turnRight()
moveForward()
}
就是这么简单的一个逻辑,如果碰上那种断头路,要么是原地兜圈子,要么就是不断要跳下悬崖。每次遇到需要使用right hand rules的场景,都会暗下决心,要想出种一劳永逸的方法,每次都失败。因为平面问题解决了,还有上山下海,其实能够解决现实问题就好。
等问题出现,我再告诉大家。
根据flask官网介绍,使用虚拟环境来管理项目的依赖,包括开发与生产环境。
因为随着Python项目增多,很有可能要与不同的python库、甚至不同版本的python打交道。一个项目的新版本库文件与另外一个项目可能不兼容。
虚拟环境独立于python库,一个虚拟环境匹配一个项目。为一个项目安装的包不会影响其他项目包或系统包。
Python绑定venv模块来创造虚拟环境。
macOS/Linux
$ mkdir flaskproject
$ cd flaskproject
$ python3 -m venv venv
macOS/Linux
$ . venv/bin/activate
这里需要注意,这个“.”和venv之间要有空格,参见stackoverflow的解释:
. venv/bin/activate
or
source venv/bin/activate
在venv环境下,如果直接启动flask服务:
flask run
会有如下红色警告信息,因为flask默认开发者是生产环境下工作,而开发环境不稳定,所以会提示如下告警。
因此需要进行设置
(venv) MDMacPro/Users/XXXXXXXXXXXX/flaskr/flaskproject/bmi[23:58]export FLASK_ENV=development
使用git checkout 2a 把对应project的source code复制到visual studio里面
由于已经通过git启动了相关程序,因此会展示如下内容。
如果对git上的源代码进行了修改,可以使用git reset –hard放弃所有修改
(venv) MDMacPro/Users/madapapa/Study/madapapa.com/flaskr/flaskproject/flaskygit:(32acca2) ✗ [12:07]git reset --hard
HEAD is now at 32acca2 Chapter 2: Dynamic routes (2b)
(venv) MDMacPro/Users/madapapa/Study/madapapa.com/flaskr/flaskproject/flaskygit:(32acca2) [12:09]git checkout 3a
Previous HEAD position was 32acca2 Chapter 2: Dynamic routes (2b)
HEAD is now at e020af8 Chapter 3: Templates (3a)
在python里,进行http相关的请求,则requests库是事实标准,这个库将复杂的http请求命令,封装在简单、优美的api里。
简单的request如get、post,当然也可以在此基础上增加鉴权功能,或者通过配置请求来防止应用的速度变慢。
使用pip在python里安装requests库,如果是python3,则是pip3
$ pip install requests
使用requests也很简单,如下
import requests
最普通常见的HTTP请求是GET。通过get,你可以获得指定的资源。
requsets.get()
当status_code返回200时,说明你的请求成功,而且服务器返回了你所请求的数据。
因此可以直接利用response的布尔属性来做一些简单判断,不过这种情况就不一定是返回200了,因为只要返回代码在200~400之间,都认为响应成功,但是不一定返回了消息内容(比如204就是这样)
对比content,text,json等的类型。
使用VS code的remote ssh功能,昨天在mac电脑上一切顺利。今天在设置办公室的windows10,遇到如下报错(使用了参考1文章里的内容,因为我解决问题后,没法复现)
[14:18:57.722] Got some output, clearing connection timeout
[14:18:57.751] > 过程试图写入的管道不存在。
[14:18:58.010] "install" terminal command done
[14:18:58.011] Install terminal quit with output: 过程试图写入的管道不存在。
[14:18:58.011] Received install output: 过程试图写入的管道不存在
解决方法很简单,按照参考文章的建议,将ssh目录下(C:\Users\XXXXX.ssh\known_hosts)的known_hosts文件内记录的服务器信息删除,任何文本编辑器打开后做如下操作,当然不是真的删除,屏蔽就好。
当然,也走了弯路,第一次按照参考2文章去做了修改,发现无效。不过这篇文章也提供了VS Code SSH本地配置文件的修改方法,也算有些用处。
编写web应用服务器报,TypeError: a bytes-like object is required, not ‘str’错误。
因为python2和python3的版本有些差异,而python3最重要的新特性也是对文本和二进制数据做了更清晰的区分。
文本用unicode编码,为str类型,二进制数据则为bytes类型
import socket,sys
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('www.madapapa.com',80))
#code=str.encode('GET /api.json HTTP/1.0\r\n\r\n')
#s.send(code)
s.send('GET /api.json HTTP/1.0\r\n\r\n')
while 1:
buf = s.recv(1000)
if not buf:
break
sys.stdout.write(buf)
s.close()
在python2的环境下运行,执行结果如下
import socket,sys
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('www.madapapa.com',80))
#s.send(str.encode('GET /api.json HTTP/1.0\r\n\r\n'))
s.send('GET /api.json HTTP/1.0\r\n\r\n'.encode())
while 1:
buf = s.recv(1000).decode()
#s1 = buf.decode()
if not buf:
break
sys.stdout.write(buf)
s.close()
在默认环境下运行(python3),执行结果如下
套接字
套接字是一套用C语言写成的应用程序开发库,它首先是一个库。主要作用就是实现进程间通信和网络编程,因此在网络应用开发中被广泛使用。
套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。
在Python中可以基于套接字来使用传输层提供的传输服务,并以此进行开发网络应用。实际开发中使用的套接字可以分为三类:流套接字(TCP套接字)、数据报套接字和原始套接字。
流式套接字
流式套接字(SOCK-STREAM)。它提供了一种可靠的、可以进行双向连接的数据传输服务。其实现了数据无差错、无重复的发送。流式套接字自身便内设了流量控制功能。在TCP/IP协议簇中,使用TCP协议来实现字节流的传输,当用户想要发送大批量的数据或者对数据传输有较高的要求时,可以使用流式套接字。
数据报套接字
数据报套接字(SOCK-DGRAM)。它提供了一种不可靠的双向数据传输服务。数据包以独立的形式被发送,不提供可靠性保证。数据在传输过程中可能会丢失或重复,并且不能保证在接收端按发送顺序接收数据。在TCP/IP协议簇中,使用UDP协议来实现数据报套接字。在出现差错的可能性较小或允许部分传输出错的应用场合,可以使用数据报套接字进行数据传输,这样通信的效率较高。
原始套接字
原始套接字(SOCK-RAW)。该套接字允许对较低层协议(如IP或ICMP)进行直接访问,常用于网络协议分析,检验新的网络协议实现,也可用于测试新配置或安装的网络设备。
上述就是套接字的大体知识,对套接字有了一定的了解,我们就可以步入正题了。
TCP套接字
TCP套接字就是上面所说的流式套接字,可以使用TCP协议提供的传输服务来实现网络通信的编程接口。
在Python中可以通过创建socket对象并指定type属性为SOCK_STREAM来使用TCP套接字。
由于一台主机可能拥有多个IP地址,所以作为服务器端的程序,需要在创建套接字对象后将其绑定到指定的IP地址和端口上。
这个端口是指对IP地址的扩展,用于区分不同的服务。
不同的服务通常与相对的端口所绑定。
当服务器收到用户请求时就可以根据端口号来确定到底用户请求的是何种服务。
关于服务于端口的绑定类型,我们会在之后的开发的当中具体描述。
如何用Python设置一个客户端的功能,简易代码如下:
fromsocketimportsocket
def main():
client= socket()
client.connect((‘192.168.1.8’, 1080))
print(client.recv(1024).decode(‘utf-8’))
client.close()
if__name__ == ‘main‘:
main()
上述代码就实现了客户端的功能,它可以与服务器进行通信。当然,上述代码只能作为一个最简单的客户端构建方式。更复杂的构建方式,学记将在之后的学习中为大家继续介绍。
在根目录下,编辑一个测试用的api小文件,然后通过浏览器(safari和chrome,地址为本地电脑地址)、终端curl(分别从vps和本地进行)的方式获取该文件。
vi /var/log/nginx/access.log
来查看刚才的api文档的获取记录
139.XXXXX - - [13/Nov/2021:14:34:22 +0800] "GET /api.json HTTP/1.1" 200 22 "-" "curl/7.68.0"(VPS方式)
223.XXXXX - - [13/Nov/2021:14:35:19 +0800] "GET /api.json HTTP/1.1" 200 22 "-" "curl/7.77.0"(本机方式)
223.XXXXX - - [13/Nov/2021:14:36:28 +0800] "GET /api.json HTTP/1.1" 200 22 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"(本机方式)
223.XXXXX - - [13/Nov/2021:14:36:28 +0800] "GET /favicon.ico HTTP/1.1" 404 188 "http://madapapa.com/api.json" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"(本机方式)
下面是刚刚发布了这篇blog后的日志变化情况,可以看到从本机进行了post操作
223.XXXXX - - [13/Nov/2021:14:59:24 +0800] "POST /wordpress/xmlrpc.php HTTP/1.1" 200 3493 "-" "MWeb%20Pro/917 CFNetwork/1325.0.1 Darwin/21.1.0"
首先,nginx -t发现正确配置文件地址
[11:10]/nginx -t
nginx: [warn] conflicting server name "localhost" on 0.0.0.0:80, ignored
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
然后vi nginx.conf,发现根目录为 /usr/share/nginx/html,编辑index.html即可
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
root /usr/share/nginx/html;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
#
location / {
index index.php index.html index.htm;
前序操作和centos相仿,在nginx.conf下没有index.html内容,需要对sites-available下default进行编辑
/etc/nginx/sites-available
# vi default
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name _;
按照10分钟、30分钟、1小时来排练