网址组成(四部分)

  协议  http,https (https是加密的http)

  主机  g.cn zhihu.com之类的网址

  端口 HTTP协议默认80,因此一般不用填写

  路径 下面的 / 和 /question/31838184

http://www.zhihu.com/

http://www.zhihu.com/question/31838184

电脑通信靠IP地址,IP地址记不住就发明了域名(domain name),然后电脑自动向DNS服务器(domain name server)查询域名对用的IP地址

比如g.cn这样的网址,可以通过电脑的ping程序查出对应的IP地址

--> ping g.cn

PING g.cn(74.125.69.160):56 data bytes

端口是什么

一个比喻

用邮局互相写信的时候,ip相当于地址(也可看做邮编,地址是域名)

端口是收信人姓名(因为一个地址比如公司,家只有一个地址,但是却可能有很多收信人)

端口就是一个标记收信人的数字

端口是一个16位的数字,所以范围是0-65535(2**16)

-------HTTP协议---------

一个传输协议,协议就是双方都遵守的规范

为什么叫超文本传输协议呢,因为收发的是文本信息

1 浏览器(客户端)按照规定的格式发送文本数据(请求)到服务器

2 服务器解析请求,按照规定的格式返回文本数据到浏览器

3 浏览器解析得到的数据,并做相印的处理

请求和返回时一样的数据格式,分为四部分:

1 请求行或响应行

2 Header (请求的Header中Host字段是必须的,其他都是可选的)

3 、\r\n\r\n (连续两个换行回车符,用来分隔Header和Body)

4 Body(可选)

请求的格式 ,注意大小写(这是一个不包含Body的请求):

原始数据如下:

'GET / HTTP/1.1\r\nh\  host:g.cn\r\n\r\n'

打印出来如下

GET / HTTP/1.1

Host: g.cn

其中

1 GET 是请求方法(还有POST等

2  / 是请求路径(这代表根路径)

3 HTTP/1.1中,1.1是版本号,通用了20年

具体字符串是'GET / HTTP/1.1\r\nhost:g.cn\r\n\r\n'

返回的数据如下
HTTP/1.1 301 Moved Permanently
Alternate-Protocol: 80:quic,p=0,80:quic,p=0
Cache-Control: private, max-age=2592000
Content-Length: 218 // Body部分的长度
Content-Type: text/html; charset=UTF-8 // Body是什么类型的 文本类型html格式 并且编码是utf8
Date: Tue, 07 Jul 2015 02:57:59 GMT
Expires: Tue, 07 Jul 2015 02:57:59 GMT
Location: http://www.google.cn/
Server: gws // google webserver
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block

Body部分太长先不贴了

其中响应行(第一行)

1 HTTP/1.1 是版本号

2 301 是状态码, 参见文末链接

3 Moved Permanently 是状态码的描述

浏览器会自己解析Header部分,然后将Body显示成网页

---------web服务器做什么-----------

主要是解析请求,发送相应的数据给客户端

例如附件中的代码(client.py)就是模拟浏览器发送HTTP请求给服务器并把收到的所有信息打印出来(使用的是最底层的socket,现阶段不必关心这种底层,web开发是上层开发)

# coding: utf-8

import socket

# socket 是操作系统用来进行网络通信的底层方案
# 简而言之, 就是发送 / 接收数据 # 创建一个 socket 对象
# 参数 socket.AF_INET 表示是 ipv4 协议
# 参数 socket.SOCK_STREAM 表示是 tcp 协议
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 这两个其实是默认值, 所以你可以不写, 如下
# s = socket.socket()
# s = ssl.wrap_socket(socket.socket()) # 主机(域名或者ip)和端口
host = 'g.cn'
port = 80
# 用 connect 函数连接上主机, 参数是一个 tuple
s.connect((host, port)) # 连接上后, 可以通过这个函数得到本机的 ip 和端口
ip, port = s.getsockname()
print('本机 ip 和 port {} {}'.format(ip, port)) # 构造一个 HTTP 请求
http_request = 'GET / HTTP/1.1\r\nhost:{}\r\n\r\n'.format(host)
# 发送 HTTP 请求给服务器
# send 函数只接受 bytes 作为参数
# str.encode 把 str 转换为 bytes, 编码是 utf-8
request = http_request.encode('utf-8')
print('请求', request)
s.send(request) # 接受服务器的响应数据
# 参数是长度, 这里为 1023 字节
# 所以这里如果服务器返回的数据中超过 1023 的部分你就得不到了
response = s.recv(1023) # 输出响应的数据, bytes 类型
print('响应', response)
# 转成 str 再输出
print('响应的 str 格式', response.decode('utf-8'))

client.py

import socket

# 这个程序就是一个套路程序, 套路程序没必要思考为什么会是这样
# 记住套路, 能用, 就够了
# 运行这个程序后, 浏览器打开 localhost:2000 就能访问了
#
# 服务器的 host 为空字符串, 表示接受任意 ip 地址的连接
# post 是端口, 这里设置为 2000, 随便选的一个数字
host = ''
port = 2000 # s 是一个 socket 实例
s = socket.socket()
# s.bind 用于绑定
# 注意 bind 函数的参数是一个 tuple
s.bind((host, port)) # 用一个无限循环来处理请求
while True:
# 套路, 先要 s.listen 开始监听
# 注意 参数 5 的含义不必关心
s.listen(5)
# 当有客户端过来连接的时候, s.accept 函数就会返回 2 个值
# 分别是 连接 和 客户端 ip 地址
connection, address = s.accept() # recv 可以接收客户端发送过来的数据
# 参数是要接收的字节数
# 返回值是一个 bytes 类型
request = connection.recv(1024) # bytes 类型调用 decode('utf-8') 来转成一个字符串(str)
print('ip and request, {}\n{}'.format(address, request.decode('utf-8'))) # b'' 表示这是一个 bytes 对象
response = b'<h1>Hello World!</h1>'
response = b'HTTP/1.1 233 VERY OK\r\n\r\n<h1>Hello World!</h1>'
# 用 sendall 发送给客户端
connection.sendall(response)
# 发送完毕后, 关闭本次连接
connection.close()

http.py

HTTP Header

GET / HTTP/1.1
Host: localhost:2000
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9 GET /favicon.ico HTTP/1.1
Host: 127.0.0.1:2000 // 必须需要
Connection: keep-alive // 服务器不会立即关闭连接 下次浏览器会继续用这个连接发送请求 TC协议P链接
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8 // 可以接收什么数据 左边类型右边格式 ,逗号分隔 ;分号分隔q=0.9是权重
Referer: http://127.0.0.1:2000/
Accept-Encoding: gzip, deflate, br // 能接收的编码 压缩的格式 这是个压缩算法  
Accept-Language: zh-CN,zh;q=0.9 // 权重 等价优先级

课程参考书

---如果 Python 基础不扎实, 可以参考 Python 学习手册

HTML CSS 知识只推荐一本(之后会有专门的课讲解 CSS), 自行学习 https://item.jd.com/1060167433.html

最新文章

  1. hiho #1325 : 平衡树&#183;Treap
  2. php完全销毁session
  3. iOS开发数据库篇—SQLite的应用
  4. Xml命名空间浅析
  5. 【USACO】第一章总结
  6. 《ArcGIS Engine+C#实例开发教程》第二讲 菜单的添加及其实现
  7. lantern蓝灯导致IE和一些软件不能上网解决方法
  8. winform使用xml作为数据源
  9. chr()、unichr()和ord(),全半角转换,ValueError: unichr() arg not in range() (wide Python build)
  10. PowerShell 远程执行任务
  11. thinter中button按钮控件(三)
  12. Spring 框架
  13. JVM内存分配及GC流程
  14. linux kernel 源码安装
  15. Mongodb集群与分片 1
  16. MAC快捷键使用大全
  17. 点击select下拉框,触发事件
  18. 03JavaScript 输出
  19. JS高级 1
  20. Comet OJ CCPC-Wannafly Winter Camp Day1 (Div2, online mirror) F.爬爬爬山-最短路(Dijkstra)(两个板子)+思维(mdzz...) zhixincode

热门文章

  1. 简单实现MemCachedUtil
  2. python 用 __all__ 暴露接口
  3. 限制mongodb内存占用过高方法
  4. 设计模式(Python)-策略模式
  5. harbor rest api 转graphql api
  6. redis的maxmemory与maxmemory-policy关系
  7. VMware ESXi 网卡
  8. WinForm应用程序中实现自动更新功能
  9. Java与SQL Server, MySql, Oracle, Access的连接方法以及一些异常解决
  10. Window 端口占用