Day5 PythonWeb全栈课程课堂内容
1. 内容
- IP地址介绍及分类
- 端口介绍
- socket的简单
- UDP发送及接收数据
- UPD聊天器
2. 前导
现有需求:
a.py
a = "hello world"
print(a)
b.py
print(a)
不通过导入模块的方式,如何实现在 a.py
中存数据, b.py
读数据。
这都是同以计算机,如果不同计算机之间进行传输通信,那么就会使用到网络。比如QQ,微信等APP。
3. 计算机网络的发展及基础网络概念
两台电脑的通信
- 网线
- 网卡
- 唯一标识mac地址,但复杂。使用ip地址唯一标识。
IP地址与IP协议
规定网络地址的协议叫ip协议,它定义的地址称为ip地址。广泛采用的v4版本的即ipv4,它规定网络地址由32位2进制表示。
注意:
- 一个ip地址通常写成四段十进制数
- 范围0.0.0.0-255.255.255.255
windows和Linux查看网卡信息
- Linux中
ifconfig
- windows中
ipconfig
IP地址分类
以太网
- 交换机为了解决多台机器之间的通信问题。
广域网
网关的概念——局域网中的机器想要访问局域网外的机器,需要通过网关访问。
端口
端口分类
1.知名端口(well known ports)
-
80端口分配给HTTP服务
-
21端口分配给FTP服务
-
- 范围是从0到1023
2.动态端口
- 动态端口的范围是从1024-65535
注意:
- 在同一时间只会有一个程序占用一个端口,不可能在同一个计算机上同一时间有两个程序占用一个端口。
4. 公网IP、内网IP、NAT转换
在日常开发中会经常听到,某些系统(支付系统、反欺诈系统)要求客户端上送:公网IP(即互联网IP地址)和内网IP(即局域网IP地址),它们分别是什么呢?有什么区别的?又有什么联系呢?另外,提到公网IP和内网IP,就不得不提NAT路由转换,NAT又是什么呢?
公网IP和内网IP的联系
每台电脑都必须要一个公网IP吗?
不是。我们都知道,IPv4中的IP地址的数量是有限的(所以现在都在搞IPv6),每次把一部分地址分配出去,那么就意味着能够用来分配的IP地址就更少了,而且随着现在手机、电脑等智能设备的快速发展,如果每个手机或者电脑都要求一个IP地址,那么显然IP地址是不够用的。
为了解决这个问题,我们可以采取这样的策略:例如对于一个公司来说,每个公司都会有一个属于自己公司的内网(也可以称之为局域网)。
内网(学名叫局域网)是在一个局部的地理范围内,一般可以是是几米内(比如家庭内网),也可以是方圆几千米以内(比如一个大学内网),将各种计算机、外部设备和数据库等互相联接起来组成的计算机通信网。
内网IP的作用
1、内网主要作用有哪些?
- 共享传输信道:简单地理解就是不需要每台电脑一个外网IP地址。
- 传输速率高:内网之间的电脑因为没有外网网络拓扑的复杂性,所以互相通信的网络可以很快。
- 误码率低:因为通信距离很近,所以误码率很低,换句话说就是网络很稳定。
2、公司的内网是如何实现内网IP地址分配和管理的?
假如我们给公司A分配了一个IP=192.168.1.1。我们把这个IP作为公司A内网的网关吧。 在公司A的内网里面有3台电脑,如果这三台电脑要上网的话,我们需要给他分配一个IP,那么就像上一节提到的:我们一定需要去申请3个IP地址来使用吗?
我们不一定需要去申请3个IP的,在我们这个内网里,我们可以指定自己的规则,例如,我们可以给这三台电脑随便分配三个IP(请注意,这三个IP不是去申请的,而且我自己随意给它分配的)。分别分配电脑A = 192.168.1.2 电脑B = 192.168.1.3 电脑C = 192.168.1.4。
而这个规则可以由我们的内网网关来管理,就像下面这样:
NAT技术-实现内网电脑访问外网的能力
假如电脑A想要访问百度,百度的IP我们假设为:172.168.30.3,我们都知道,电脑A的IP是我们虚构的,实际上可能并不存在这样一个IP,如果用电脑A的IP去访问百度,那肯定行不通。我们也知道,由于百度和电脑A不在一个局域网内,所以A要访问百度,那么必须得经过网关。而网关的这个IP地址,是真实存在的,是可以访问百度的。
为了让电脑可以访问百度,那么我们可以采取这样的方法:让网关去帮助电脑A访问百度,百度把结果传递给网关,然后网关再把结果传递给电脑A,这样不就可以解决了?
不过电脑A、B、C都可能拜托网关去帮忙访问百度,而百度返回的结果的目标IP都是网关的IP=192.168.1.1。那么网关该如何进行区分这结果是电脑A、B还是C的呢?
我们去访问百度的时候,不是需要指定一个端口吗?只要我们把电脑A的IP + 端口 映射成 网关的IP+端口,不就可以唯一确定身份了?
例如电脑A用端口60去访问百度,网关把电脑A的IP+端口60 映射成 网关的IP+端口80 不就可以了?
百度把结果返回给网关的80端口之后,网关再通过映射表,就可以把结果返回给 A的60端口 了。 如果B也是用60端口去访问百度的话,也是一样,可以把它映射到90端口。
这种方法地址的映射转换,我们也称之为网络地址转换,英文为 Network Address Translation,简称NAT。
而像A、B、C这样的IP地址我们也称之为内网IP,即内网IP;而像网关,百度这样的IP我们称之为外网IP(即互联网公网IP)。
5. socket简介
TCP/IP协议
计算机与网络设备要相互通信,双方就必须基于相同的方法。比如,如何探测到通信目标、由哪一边先发起通信、使用哪种语言进行通信、怎样结束通信等规则都需要事先确定。不同的硬件、操作系统之间的通信,所有的这一切都需要一种规则。而我们就把这种规则称为协议(protocol)。
TCP/IP 是互联网相关的各类协议族的总称,比如:TCP,UDP,IP,FTP,HTTP,ICMP,SMTP 等都属于 TCP/IP 族内的协议
TCP/IP协议是Transmission Control Protocol/Internet Protocol的简写,即传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议、Internet国际互联网络的基础,由网络层的IP协议和传输层的TCP协议组成。TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。
然而,TCP/IP协议并不是国际官方组织制定的标准,而是民间组织(一些大型国际厂商、高等院校)自行商定的标准,因为更简便,推广力度更大,而成为了事实上的标准。
TCP/IP网络模型四层模型从根本上和OSI七层网络模型是一样的,只是合并了几层
在TCP/IP协议中,其各层之间的通信机制,大致如下图所示:
socket介绍
socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。白话说,socket就是两个节点为了互相通信,而在各自家里装的一部’电话’。
加入socket后,网络关系如下图所示:
- 使用socket
"""
文件操作
打开文件
操作文件
关闭文件
套接字使用
创建套接字
使用套接字 收/发数据
关闭套接字
"""
import socket
# family 协议组 type 套接字类型
s = socket.socket(family=socket.AF_INET,type=socket.SOCK_DGRAM)
print(s)
6. udp发送与接收数据
udp发送数据
实现步骤:
- 1.创建套接字
- 2.使用套接字收/发数据
- 3.关闭套接字
'''
- 1.创建套接字
- 2.使用套接字收/发数据
- 3.关闭套接字
'''
import socket
def main():
# 创建套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_socket.sendto(b'hello', ('192.168.1.7',8080))
udp_socket.close()
if __name__ == '__main__':
main()
- 连续输入
import socket
def main():
# 创建套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
send_data = input("Please input your data:")
if send_data == 'q':
break
udp_socket.sendto(send_data.encode('utf-8'), ('192.168.1.7', 8080))
udp_socket.close()
if __name__ == '__main__':
main()
7. udp接收数据
udp接收数据
实现步骤:
- 1.创建套接字
- 2.绑定本地信息(IP和端口)
- 3.接受数据
- 4.打印数据
- 5.关闭套接字
import socket
def main():
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定本地信息
addr = ('192.168.1.7',7070)
udp_socket.bind(addr)
# 接收数据
recv_data = udp_socket.recvfrom(1024)
print(recv_data)
udp_socket.close()
if __name__ == '__main__':
main()
- 连续接收
import socket
def main():
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定本地信息
addr = ('192.168.1.7',7070)
udp_socket.bind(addr)
# 接收数据
while True:
recv_data = udp_socket.recvfrom(1024) # 1024接收本次最大字节数
if recv_data[0].decode('utf-8') == 'q':
break
print('%s: %s'%(str(recv_data[1]),recv_data[0].decode('utf-8')))
udp_socket.close()
if __name__ == '__main__':
main()
- 特殊情况
- 同样的udp发送数据中也绑定地址
import socket
def main():
# 创建套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udp_socket.bind(('192.168.1.7',7071))
while True:
send_data = input("Please input your data:")
if send_data == 'q':
break
udp_socket.sendto(send_data.encode('utf-8'), ('192.168.1.7', 8080))
udp_socket.close()
if __name__ == '__main__':
main()
- 端口相等
8.udp聊天器
# @Time : 2020/12/20 17:15
# @Author : Sam
# @File : udp聊天器.py
# @Software: PyCharm
import socket
def send_data(udp_socket):
# 发送数据
send_data = input('Please your input data:')
udp_socket.sendto(send_data.encode('utf-8'), ('192.168.1.7', 7070))
def recv_data(udp_socket):
data = udp_socket.recvfrom(1024)
print('%s: %s' % (str(data[1]), data[0].decode('utf-8')))
def main():
# 创建套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定地址和端口
udp_socket.bind(('192.168.1.7', 7070))
while True:
send_data(udp_socket)
recv_data(udp_socket)
udp_socket.close()
if __name__ == '__main__':
main()