Day5 PythonWeb全栈课程课堂内容

1. 内容

  • IP地址介绍及分类
  • 端口介绍
  • socket的简单
  • UDP发送及接收数据
  • UPD聊天器

2. 前导

现有需求:

  • a.py
a = "hello world"
print(a)
  • b.py
print(a)

不通过导入模块的方式,如何实现在 a.py 中存数据, b.py 读数据。

image.png

image.png

这都是同以计算机,如果不同计算机之间进行传输通信,那么就会使用到网络。比如QQ,微信等APP。

3. 计算机网络的发展及基础网络概念

两台电脑的通信

image.png

  • 网线
  • 网卡
  • 唯一标识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地址分类

image.png

以太网

image.png

  • 交换机为了解决多台机器之间的通信问题。

广域网

image.png

网关的概念——局域网中的机器想要访问局域网外的机器,需要通过网关访问。

端口

image.png

端口分类

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。

而这个规则可以由我们的内网网关来管理,就像下面这样:

652d81df46a5485b80d4836f6c882061_tplv-k3u1fbpfcp-watermark.png

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 不就可以了?

785100f834bd4038b14d7d19caa5d4af_tplv-k3u1fbpfcp-watermark.png

百度把结果返回给网关的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七层网络模型是一样的,只是合并了几层

image.png

在TCP/IP协议中,其各层之间的通信机制,大致如下图所示:

image.png

socket介绍

socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。白话说,socket就是两个节点为了互相通信,而在各自家里装的一部’电话’。

加入socket后,网络关系如下图所示:

image.png

  • 使用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()

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值