温故而知新--day5

ip地址

IP是英文Internet Protocol的缩写,意思是“网络之间互连的协议”,也就是为计算机网络相互连接进行通信而设计的协议。当多个设备要进行通信的时候,ip地址必须唯一。

IP地址=网络地址+主机地址,(又称:网络号和主机号组成)

网络号、主机号的确定需要“子网掩码”

公网ip分类

  • A类:该类IP地址的最前面为“1000”(1.0.0.0-126.0.0.0)(默认子网掩码:255.0.0.0或 0xFF000000)
  • B类:该类IP地址的最前面为“1100”(128.1.0.0-191.255.0.0)(默认子网掩码:255.255.0.0或0xFFFF0000)
  • C类:该类IP地址的最前面为“1110”(192.0.1.0-223.255.255.0)(子网掩码:255.255.255.0或 0xFFFFFF00)
  • D类:是多播地址。该类IP地址的最前面为“1110”,所以地址的网络号取值于224~239之间。一般用于多路广播用户。
  • E类:是保留地址。该类IP地址的最前面为“1111”,所以地址的网络号取值于240~255之间。

私有地址

私有地址是不能直接在Internet网络中应用的,要上Internet的话要转为公有地址。私有ip有以下几种:

  • A::10.0.0.0-10.255.255.255 即10.0.0.0/8
  • B:172.16.0.0-172.31.255.255即172.16.0.0/12
  • C:192.168.0.0-192.168.255.255 即192.168.0.0/16

子网掩码

子网掩码是用来判断任意两台计算机的ip地址是否属于同一子网络的根据。最为简单的理解就是两台计算机各自的ip地址与子网掩码进行and运算后,得出的结果是相同的,则说明这两台计算机是处于同一个子网络上的,可以进行直接的通讯。


IP地址与子网掩码

图中还可以写成:192.168.1.1/24

24就是1的个数

端口

只使用ip地址进行通信只能精确到某台主机,因此加入了可以区别不同程序的标识符:端口。

端口使用2个比特来表示,范围为是0~25535。

端口分为两种:

  • 周知端口(Well Known Ports)

    • 周知端口是众所周知的端口号,范围从0到1023,其中80端口分配给WWW服务,21端口分配给FTP服务等。
    • 周知端口的监听需要有root权限。
  • 动态端口(Dynamic Ports)
    • 动态端口的范围是从1024到65535。之所以称为动态端口,是因为它一般不固定分配某种服务,而是动态分配。

更多见:

iso七层


详细

socket

socket为套接字,是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。socket是"打开—读/写—关闭"模式的实现。

TCP

TCP/IP协议是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。

TCP协议就像打电话一样,有“打-通话-挂”三个过程,“打”:是指客户端与服务端建立链接(三次握手);“通话”:两端进行通信;“挂”:客户端或服务端发起断开请求。

注:seq:"sequance"序列号;ack:"acknowledge"确认号;SYN:"synchronize"请求同步标志;;ACK:"acknowledge"确认标志";FIN:"Finally"结束标志。

在python中简单使用TCP

参考tcp cs模型:

"""
服务端
""" import socket
tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # SOCK_STREAM是tcp协议 # 绑定ip地址和监听的端口
tcp_sock.bind(("", 8899)) # ip地址为空字符串时,指的是本机
tcp_sock.listen(50) # 缓存区大小 # 等待链接
new_sock, addr = tcp_sock.accept() recv_data = new_sock.recv(1024) # 收
print(recv_data.decode())
new_sock.send(recv_data) # 发
# 关闭
new_sock.close()
tcp_sock.close() """
客户端
""" import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接
s.connect(("127.0.0.1", 8899))
s.send(b"hello") data = s.recv(1024)
print(data.decode()) s.close()

并发

上面这个简单的例子只能简单处理一个请求,要想同时处理多个请求,可以用一下方法实现:

  • 多线(进)程

    """
    服务端
    """ import socket
    from concurrent.futures import ThreadPoolExecutor def process_client(client, addr):
    """
    处理过来的链接,进行收发处理
    """
    try:
    while True:
    recv_data = client.recv(1024) # 收
    print(recv_data.decode())
    client.send(recv_data) # 发
    finally:
    # 关闭
    client.close() def main(): tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_sock.bind(("", 8899)) # ip地址为空字符串时,指的是本机
    tcp_sock.listen(50) # 缓存区大小 # 等待链接
    try:
    while True:
    new_sock, addr = tcp_sock.accept()
    with ThreadPoolExecutor(12) as t:
    t.submit(process_client, new_sock, addr)
    # 假如是多进程的话,此时应该加上 new_socke.close()
    # 因为在使用多进程时,资源会再复制一份到另一进程
    finally:
    tcp_sock.close() if __name__ == '__main__':
    main() """
    客户端
    """ import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接
    s.connect(("127.0.0.1", 8899)) while True:
    data = input(">>>")
    if not data:
    continue
    s.send(data.encode())
    print(s.recv(1024).decode()) s.close()
  • socketserver

    python中除了有socket库提供socket支持外,还有socketserver提供服务器中心类,可以简化网络服务器的开发。

    使用步骤:

    • 1、创建一个继承socketserver.BaseRequestHandler的类

    • 2、类中必须重写一个名为handler的方法

    • 3、实例化一个服务器类,传入服务器的地址和请求处理程序类

    • 4、调用serve_forever()事件循环监听

    注意:类中的self.request在TCP时为已链接的套接字对象;UDP时为(data, udp socket对象) 需要借助self.client_address发数据

    """
    服务端
    """ import socketserver class MyServer(socketserver.BaseRequestHandler):
    def handle(self) -> None:
    print(self.client_address) # 地址
    while True:
    recv_data = self.request.recv(1024) # 收
    # print(recv_data.decode())
    self.request.send(recv_data) # 发 def main():
    s = socketserver.ThreadingTCPServer(("", 8899), MyServer)
    s.serve_forever() if __name__ == '__main__':
    main()

    更多见:socketserver模块使用方法

  • io多路复用

    见day4的最后例子

UDP

无连接的、简单的、面向数据包的传输层协议。

简单收发例子

"""
服务端
""" import socket udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_sock.bind(("", 8899)) while True:
data, addr = udp_sock.recvfrom(1024)
print(data)
udp_sock.sendto(data, addr) """
客户端
""" import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) data = input(">>>")
# 发送消息,数据+ip端口
s.sendto(data.encode(), ("127.0.0.1", 8899))
print(s.recvfrom(1024)) s.close()

udp广播

要点:

  1. 发送地址为<broadcast>
  2. 设置socket选项
    """
    udp广播
    局域内,只要监听8899端口,都能收到消息
    """ import socket udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 发送的地址
    ip_port = ("<broadcast>", 8899)
    # 修改socket选项, 固定格式
    udp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
    udp_sock.sendto(b"test", ip_port) while True:
    recv_data = udp_sock.recvfrom(1024)
    print(recv_data)

http

什么是http协议

http协议是Hypertext Transfer Protocol --(超文本传输协议)的缩写,在互联网领域用得非常多的通讯协议。

HTTP是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。

HTTP协议是建立在TCP协议之上的一种应用。

1)在HTTP 1.0中,客户端的每次请求都要求建立一次单独的连接,在处理完本次请求后,就自动释放连接。

2)在HTTP 1.1中,可以在一次连接中处理多个请求,并且多个请求可以重叠进行,不需要等待一个请求结束后再发送下一个请求。

http的过程

  1. 服务端监听80端口,等待请求
  2. 客户端(一般为浏览器)发起请求
  3. 服务端处理请求,返回数据
  4. 客户端或服务端断开链接

URI和URL

URI用字符串标示某一互联网资源,而URL表示资源的地点。可见URL是URI的子集。

URI要使用涵盖全部必要信息的URI、绝对URL以及相对URL。

相对URL是指从浏览器中基本URI处理的URL,来先看下URI的格式:

请求报文


请求报文
POST /test/index.html HTTP/1.1
Accept: */*
Accept-Language: zh-cn
host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 12
Connection:close
sn=123&n=asa

响应报文

HTTP/1.1 200 OK
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2003 13:23:42 GMT
Content-Length:112 <html>
<head>
<title>HTTP响应示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>

请求方法

  • GET

    服务器将URL定位的资源放在响应报文的数据部分,回送给客户端

    利用在URL的结尾表示传参,多个参数之间用&隔开,如/index.html?id=10&op=bind传递参数长度受限制,且不适合传送私密数据

  • POST

    POST方法将请求参数封装在HTTP请求数据中,以名称/值的形式出现,可以传输大量数据。如请求报文哪里的例子。

  • HEAD

    像GET,只不过服务端接受到HEAD请求后只返回响应头,而不会发送响应内容。适用于查看某个页面的状态。

  • PUT

    可用来传输文件,就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求url指定的位置。由于put的方法不带验证机制,任何人都可以上传文件,存在安全性问题。

  • DELETE

    用来删除文件,是与put相反的方法,delete方法按照请求url删除指定的资源。其本质和put方法一样不带验证机制。

全部方法:

状态码

状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。

1xx:指示信息--表示请求已接收,继续处理。

2xx:成功--表示请求已被成功接收、理解、接受。

3xx:重定向--要完成请求必须进行更进一步的操作。

4xx:客户端错误--请求有语法错误或请求无法实现。

5xx:服务器端错误--服务器未能实现合法的请求。

常见状态代码、状态描述的说明如下。

200 OK:客户端请求成功。

400 Bad Request:客户端请求有语法错误,不能被服务器所理解。

401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。

403 Forbidden:服务器收到请求,但是拒绝提供服务。

404 Not Found:请求资源不存在,举个例子:输入了错误的URL。

500 Internal Server Error:服务器发生不可预期的错误。

503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。

cookie

Cookie是用于维持服务端会话状态的,通常由服务端写入,在后续请求中,供服务端读取的一段文本。

cookie技术通过在请求和相应报文中写入cookie信息来控制客户端的状态。cookie会根据从服务端发送的相应报文内的一个叫做set-cookie的首部字段信息,通知客户端保存cookie。当下次客户端再往服务器发送请求的时候,客户端会自动在请求头加入cookie值后发送出去

更多:细说Cookie

session

Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。

Session对象在客户端第一次请求服务器的时候创建。

更多:cookie和session的详解与区别

https

详见此文:HTTPS科普扫盲帖

websocket

【待完成】

扩展

计算机网络基础知识总结

我的github

我的博客

我的笔记

温故而知新--day5的更多相关文章

  1. day5

    作业 作业需求: 模拟实现一个ATM + 购物商城程序 额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 每月22号出账单,每月10号为还款日,过期 ...

  2. Python学习记录day5

    title: Python学习记录day5 tags: python author: Chinge Yang date: 2016-11-26 --- 1.多层装饰器 多层装饰器的原理是,装饰器装饰函 ...

  3. sql server 基础教程[温故而知新三]

    子曰:“温故而知新,可以为师矣.”孔子说:“温习旧知识从而得知新的理解与体会,凭借这一点就可以成为老师了.“ 尤其是咱们搞程序的人,不管是不是全栈工程师,都是集十八般武艺于一身.不过有时候有些知识如果 ...

  4. jquery 基础教程[温故而知新二]

    子曰:“温故而知新,可以为师矣.”孔子说:“温习旧知识从而得知新的理解与体会,凭借这一点就可以成为老师了.“ 尤其是咱们搞程序的人,不管是不是全栈工程师,都是集十八般武艺于一身.不过有时候有些知识如果 ...

  5. javascript 基础教程[温故而知新一]

    子曰:“温故而知新,可以为师矣.”孔子说:“温习旧知识从而得知新的理解与体会,凭借这一点就可以成为老师了.“ 尤其是咱们搞程序的人,不管是不是全栈工程师,都是集十八般武艺于一身.不过有时候有些知识如果 ...

  6. 冲刺阶段 day5

    day5 项目进展 今天我们组的成员聚在一起进行了讨论,首先我们继续编写了学生管理这部分的代码,然后负责数据库的同学完成了数据库的部分,最后进行了学生管理这部分的代码复审 存在问题 因为代码不是一天之 ...

  7. python笔记 - day5

    python笔记 - day5 参考: http://www.cnblogs.com/wupeiqi/articles/5484747.html http://www.cnblogs.com/alex ...

  8. python_way ,day5 模块,模块3 ,双层装饰器,字符串格式化,生成器,递归,模块倒入,第三方模块倒入,序列化反序列化,日志处理

    python_way.day5 1.模块3 time,datetime, json,pickle 2.双层装饰器 3.字符串格式化 4.生成器 5.递归 6.模块倒入 7.第三方模块倒入 8.序列化反 ...

  9. Spark菜鸟学习营Day5 分布式程序开发

    Spark菜鸟学习营Day5 分布式程序开发 这一章会和我们前面进行的需求分析进行呼应,完成程序的开发. 开发步骤 分布式系统开发是一个复杂的过程,对于复杂过程,我们需要分解为简单步骤的组合. 针对每 ...

随机推荐

  1. java数组 简单了解

    一.关于集合 1.数组,链表和哈希表(散列表)的存储方式 (1)传统的数组结构存储数据会在内存中开辟连续得空间,结合下标从而使得可以快速访问数据,但是删除和添加数据就很浪费资源 (2)链表不需要开辟连 ...

  2. pytorch实现LeNet5分类CIFAR10

    关于LeNet-5 LeNet5的Pytorch实现在网络上已经有很多了,这里记录一下自己的实现方法. LeNet-5出自于Gradient-Based Learning Applied to Doc ...

  3. [转发]PotPlayer 无损截取视频片段

    PotPlayer 无损截取视频片段 2019-03-29 21:04:21 ForeverStrong 阅读数 2928  收藏 更多 分类专栏: 视频图像编辑   PotPlayer 无损截取视频 ...

  4. Linux 操作系统(三) 添加用户、切换用户、删除用户

    以下命令均已在 Kali Linux 验证. 1.添加用户 --1-- useradd -m username            //username 代表你所添加的用户名 --2-- passw ...

  5. Java 四种内置线程池

    引言 我们之前使用线程的时候都是使用 new Thread 来进行线程的创建,但是这样会有一些问题 每次 new Thread 新建对象性能差 线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可 ...

  6. mysql基础之mariadb库管理和表管理语句

    一.数据库管理语句 1.Syntax: CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name [create_specification] ... cr ...

  7. centos 7修改yum源

    centos系统要定期更新,前天使用sudo yum update命令更新过程中出错,安装的是x64的系统,结果更新的内容有i686的依赖包,最终由于64与32位系统依赖的原因导致更新失败,更糟糕的是 ...

  8. 『动善时』JMeter基础 — 26、使用txt文件实现JMeter参数化

    目录 1.测试计划中的元件 2.数据文件内容 3.线程组元件内容 4.HTTP信息头管理器组件内容 5.CSV数据文件设置组件内容 6.HTTP请求组件内容 7.脚本运行结果 之前我们都是使用.csv ...

  9. 『言善信』Fiddler工具 — 2、HTTP请求内容详解

    目录 1.HTTP协议介绍 2.使用Fiddler抓取一个请求 3.НТТP请求报文 (1)НТТP请求报文说明 (2)请求行 (3)请求头(Request Header) (4)请求体 4.НТТР ...

  10. Go语言网络通信---tcp群发消息

    server package main import ( "fmt" "net" "os" "time" ) func ...