网络编程.

网络编程

前言

  • 我们现在已经学会了写基本形式的python代码,假如你写了两个python文件a.py和b.py,分别去运行,你就会发现,这两个python的文件分别运行的很好。但是如果这两个程序之间想要传递一个数据,你要怎么做呢?
    • 这个问题以你现在的知识就可以解决了,我们可以创建一个文件,把a.py想要传递的内容写到文件中,然后b.py从这个文件中读取内容就可以了。
    • 思考:如果当a.py和b.py分别在不同电脑上的时候,你要怎么办呢?

      • 这就需要使用网路通信的技术了,也就是所谓的网络编程!
  • 网络编程:

    • 网络:网络通常指的是计算机中的互联网,是由多台计算机通过网线或其他媒介相互链接组成的
    • 编程:编写基于网络应用的程序
  • 为什么要学习网络编程?

    • 我们知道计算机是由硬件、 操作系统、应用程序组成的,有了这三个元素,就可以在自己的电脑上运行一些应用程序了,比如玩玩纸牌,扫扫雷什么的
    • 如果要想与其他计算机一起玩,就必须要让你的计算机和其他计算机能够互相传递数据
    • 所以说学习网络编程就是要学习利用网络来与另一台计算机相互传输数据

软件开发的架构

  • 目前我们了解的涉及到两个程序之间通讯的应用大致可以分为两种:
    • 第一种是应用类:qq、微信、网盘、优酷这一类是属于需要安装的桌面应用
    • 第二种是web类:比如百度、知乎、博客园等使用浏览器访问就可以直接使用的应用
  • 这些应用的本质其实都是两个程序之间的通讯。而这两个分类又对应了两个软件开发的架构:
    • C/S架构
    • B/S架构

C/S架构

  • C/S即:Client与Server ,中文意思:客户端与服务器端架构。
    • 学习网络编程就是要通过网络来访问另一台计算的数据,这样必然需要至少两台计算机,一台计算机上放着要分享的数据和用于分享数据的程序,另一台计算机上运行访问数据的程序,
    • 我们把提供数据的一方称之为服务器(Server),把访问数据的一方称为客户端(Client)
    • 比如:电脑上要看视频就需要装看视频的程序.例如腾讯视频,它就是客户端程序,腾讯公司的机房里运行着腾讯视频的服务器程序,所以它也是C/S构架的程序

B/S架构

  • B/S即:Browser与Server,中文意思:浏览器端与服务器端架构。
  • Browser浏览器,其实也是一种Client客户端,只是这个客户端不需要大家去安装什么应用程序,只需在浏览器上通过HTTP请求服务器端相关的资源(网页资源)即可。

网络基础

网络通讯的基本要素

  • 两台计算机要想通讯,必须要具备两个基本要素:

    • 物理连接介质

      • 人类说话需要有空气来传播震动,眼睛要看东西需要有光来传播,没有空气,没有光,则无法沟通,光和空气就是物理介质
      • 再比如电话机,要打通电话则必须先接通电话线,电流才能沿着电话线到达另一台电话机,电话线则是物理介质
      • 那么在计算机的网络通讯中物理连接介质就是网线,无线电,光纤等
    • 通讯协议/网络协议

网络协议

什么是网络协议?

网络协议就是标准,大家要遵循相同的标准才能正常交流。在计算机网络通讯过程中,发送和接收方约定用一种协议(数据格式)进行通讯,发送数据的一方严格按照一个协议(数据格式)发送数据,接收方也严格按照协议(数据格式)进行解析,这样才能进行一次完整的网络通讯。
  • 举个例子:

在后期web项目中会涉及到微信支付功能,则现在用“微信支付”的功能来举例:我们在做的是“微信扫码支付”,其中微信就规定了一套支付信息提交协议供用户来提交支付账单,拿“生成微信订单”来举例,必须要以xml格式传递以下样式参数:
<xml>
        <appid>公众账号ID</appid>
        <mch_id>商户号</mch_id>
        <detail>商品详情</detail>
        <notify_url>通知地址</notify_url>
        <out_trade_no>商户订单号</out_trade_no>
        <total_fee>下单金额(以分为单位)</total_fee>
        <sign>签名</sign>
        ...............
</xml>
由此,我们必须按照这样的规则要求去传递数据,这样微信才能返回正确的回执。回执如下:
<xml>
        <return_code>通讯成功或失败</return_code>
        <return_msg>返回信息</return_msg>
        <result_code>业务处理结果成功或失败</result_code>
        <sign>签名</sign>
        <code_url>生成订单的支付二维码</code_url>
</xml>
注意:协议是由发送方和接受方共同制定的,考虑到计算机已经发展了这么多年,所以制定的协议过程很显然我们没有机会参与了,要做的是了解通讯协议中的各种规定即可。

TCP/IP协议簇

  • TCP/IP协议

    • TCP/IP协议就是传输控制协议,又名网络通讯协议。
    • 从字面意义上讲,有人可能会认为 TCP/IP 是指 TCP 和 IP 两种协议,但是实际上TCP/IP是指利用 IP 进行通信时所必须用到的协议群的统称。
    • 作用:

      • TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准。该协议采用了4层的层级结构,每一层都呼叫它的下一层所提供的协议来完成自己的需求。
    • 然而,TCP/IP协议并不是国际官方组织制定的标准,而是民间组织(一些大型国际厂商、高等院校)自行商定的标准,因为更简便,推广力度更大,而成为了事实上的标准。
  • 那么,国际官方组织制定的标准是什么呢?是OSI七层网络模型!该模型从最顶层的应用层到最底层的物理层,一共有7层,可以通过首字进行简单记忆,也就是“应、表、会、传、网、数、物”。

osi七层模型

  • osi就是相当于计算机界的通用语言,只要按照OSI规定的标准来通讯,就能够与全世界任何一台所有计算机通讯
  • osi七层模型

    • 人们按照分工不同把互联网协议从逻辑上划分了层级:
  • 上图中最右边就是完整的七层模型,是最完整的通讯模型,虽然很详尽,但是整个通讯流程的复杂度较高,后期为了降低学习难度,将其进行了简化,于是有了中间的五层,和左边的四层。

OSI各层工作原理解析

应用层,表示层,会话层都属于应用程序层面所以重点讨论简化后的五层。
  • 物理层

    • 两台原本相互独立的计算机,想要通讯,必须建立物理连接,连接的方式多种多样,包括电缆,光缆,无线电等;
    • 物理层的功能:基于电子器件发送电流信号,根据电流的高低可以对应到数字0和1,也就是二进制数据。
    • 有了电信号的交互就可以实现网络通信了吗?
  • 数据链路层

    • 数据链路层的由来:

      • 单纯的电信号0和1没有任何意义,想要变的有意义则必须规定电信号多少位一组,每组什么意思,怎么实现呢?
    • 以太网协议:

      • 以太网协议(Ethernet)工作在数据链路层,其规定了电信号分组方式,以及一组电信号应该包含哪些内容。
      • ethernet规定一组电信号构成一个数据包,叫做‘帧’。
      • 每一数据帧分成:报头head和数据data两部分:
        • head包含:(固定18个字节):

          • 发送者/源地址,6个字节
          • 接收者/目标地址,6个字节
          • 数据类型(标签+以太类型),6个字节
        • data包含:(最短46字节,最长1500字节)

        • 数据包的具体内容:

          • head长度+data长度=最短64字节,最长1518字节,超过最大限制就分片发送。
    • mac地址

      • head中包含的源和目标地址指的是什么地址呢?

        • ethernet规定接入internet的设备都必须具备网卡,发送端和接收端的地址便是指网卡的地址,即mac地址。
      • mac地址:

        • 每块网卡出厂时都被烧制上一个世界唯一的mac地址,长度为48位2进制,通常由12位16进制数表示(前六位是厂商编号,后六位是流水线号)
    • 广播

      • 有了mac地址,同一网络内的两台主机就可以通信了.
      • ethernet协议采用最原始的方式,广播的方式进行通信,即计算机通信基本靠吼
      • 思考:如果同一网络中有100台电脑,大家都在同一时间都在互相通讯会有什么问题吗?
        • 相当于村头挂着100个大喇叭,大家都在使劲喊,结果是要听清楚说的什么内容非常费劲儿。
        • 回到计算机中,100台电脑都在那儿广播,传输速度一定是有限的,严重浪费了网络资源。
        • 所以,就会使用处在局域网中间的设备就是所谓的交换机(上图的中间那个小东西)
      • 交换机:

        • 交换机不仅负责让网络中的计算机能够互相通信,还要优化网络传输
      • 那么如何使用交换机优化多台机器在同一网络中的相互通讯呢?
        • 当pc1想要与pc2通讯前:

          • 1.pc1需要知道pc2的MAC地址,所以必须先将这个信息广播给所有的计算机,
          • 2.但是这个信息必须先交给交换机,再由交换机广播出去,
          • 3.pc2收到消息消息后发现目标MAC是自己,就回复数据给发送方pc1,
          • 4.而pc2回复的信息也必须先交给交换机,此时交换机就会记录pc2的MAC地址并将其存到自己的缓存中,
          • 5.下一次在要给pc2发数据时从缓存中查找pc2的MAC地址,
          • 6.如果找到了就直接单独给pc2发送,不在需要广播,
          • 7.如果没有则重复之前的广播过程
          • 也就是如果多台机器相互之间都进行过通讯后,则所有机器的mac地址都会存储到交换机的缓存中,则后期通讯就是相当于"点和点"的通讯方式了。这一优化功能称之为自动学习功能。
        • 第一次链接某计算机时 必须广播获取MAC地址:
        • 只要链接过一次 MAC地址就被交换机记录下了下一次就不用广播了:
        • 所以:交换机的工作原理类似类似于早期的电话交换机,电话线打到总台,总台问你要找几号?,然后将电话线插到相应的口上。
    • 网络层

      • 有了ethernet、mac地址、广播的发送方式,世界上的计算机就可以彼此通信了。
      • ethernet的广播方式通讯方式存在的问题?
        • 世界范围的互联网是由一个个彼此隔离的小的局域网组成的,如果所有的计算机都采用以太网的广播方式来寻找其他计算机,那么一台机器发送的包全世界都会收到,这就不仅仅是效率低的问题了,这会是一种灾难,(广播风暴就是这么产生的)
        • 所以:必须找出一种方法来区分哪些计算机属于同一广播域(缩小广播范围),哪些不是,如果是就采用广播的方式发送,如果不是,就采用路由的方式(向不同广播域/子网分发数据包),mac地址是无法区分哪些计算机属于同一广播域哪些不是的,它只跟厂商有关;
        • 网络层功能:

          • 引入一套新的地址用来区分不同的广播域/子网,这套地址即网络地址
        • 网络地址到底长什么样,又是如何区分子网的?

          • 网络地址就是由IP协议定义的地址,叫做IP地址。
          • IP协议是工作在网络层的协议,全称:Internet Protocol Address,翻译为互联网协议地址。
      • IP地址

        • ip协议定义的地址称之为ip地址,广泛采用的v4版本即ipv4,它规定网络地址由32位2进制表示。
        • 范围0.0.0.0-255.255.255.255
        • 一个ip地址通常写成四段十进制数,例:192.168.10.1
        • IP地址并不是随机分配的,而是有严格规范的,分为A,B,C,D,E五大类:
          • 比如:A类保留给政府机构,10.0.0.1 - 10.255.255.254,C类分配给任何需要的人,192.168.0.1 - 192.168.255.254
          • 我们的电脑ip通常都是C类的,以192.168开头,正因为C类任何人都可以用
      • 子网掩码(了解)

        • 单纯的ip地址段只是标识了ip地址的种类,无法辨识一个ip所处的子网 例:192.168.10.1与192.168.10.2并不能确定二者处于同一子网/局域网。
        • 子网掩码是一个32位地址,用于说明不同的IP地址是在局域网上,还是在远程网上。
        • 知道”子网掩码”,我们就能判断,任意两个IP地址是否处在同一个子网络。方法是将两个IP地址与子网掩码分别进行AND运算,然后比较结果是否相同,如果是的话,就表明它们在同一个子网络中,否则就不是。
        • 结论:子网掩码就是用来判断两个ip是否属于同一子网/局域网。
    • 传输层

      • 目前我们已知:可以通过物理层来建立计算机之间的链接通道,然后通过数据链路层的MAC地址,可以定位到某个局域网中的某台主机,最后通过网络层的IP地址,子网掩码,可以定位到全球范围某一局域网下的某台主机。
      • 那么问题来了:
        • 一台计算机上是不可能只能运行一个应用程序的,比如我们可以同时登陆qq和微信,那接收到的数据到底是交给微信还是qq呢?
        • 这个时候就需要应用到所谓的"端口号"了。
      • 端口号:
        • 端口是需要联网的应用程序与网卡关联的编号或者简单理解成应用程序的唯一标识。
        • 因此端口号就是需要联网的应用程序与网卡关联的编号。端口范围0-65535,0-1023为系统占用端口。
        • 重点:ip地址精确到具体的一台电脑,而端口精确到具体的程序
      • 传输层的作用:
        • 建立端口到端口的通信。
      • 其实我们发现,osi的每一层都会作用自己的一些协议,传输层也是一样的:
        • TCP和UDP就是工作在传输层的协议(后面重点讲解)
    • 应用层

      • 应用层由来:

        • 用户使用的都是应用程序(微信,支付宝等),均工作于应用层,互联网是开放的,大家都可以开发自己的应用程序,用什么样的数据格式来传输,就需要由应用程序开发者自己来制定
      • 应用层作用:

        • 规定应用程序之间交互数据的数据格式,这些数据交互的格式也就是作用在应用层之间的各种协议。

        • 这些应用程序的协议就构成了"应用层"

          • 常见协议:HTTP,FTP,SMTP等
TCP和UDP协议
什么是TCP协议
  • TCP 是面向有连接且可靠的通信传输协议,面向有连接是指在传送数据之前必须先建立连接,数据传送完成后要释放连接。并且可实现“顺序控制”和“重发控制”的机制。

  • 无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议簇中,TCP协议提供可靠的连接服务,连接是通过三次握手进行初始化的且通过四次挥手关闭连接。

    • 例如:打电话,需要双方都接通,才能进行对话
    • 优劣:效率低,数据传输比较安全
什么是UDP协议
  • UDP 是面向报文的通信传输协议,所谓面向报文,指它的传输方式是应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。UDP 是不具有可靠性的数据报协议。在 UDP 的情况下,虽然可以确保发送消息的大小,却不能保证消息一定会到达。因此,应用有时会根据自己的需要进行重发处理。
    • 例如:发短信,不需要双方建立连接。
    • 优劣:效率高,数据传输不安全,容易丢包
三次握手
  • TCP 提供面向有连接的通信传输。面向有连接是指在数据通信开始之前先做好两端之间的准备工作。
  • 所谓三次握手是指建立一个 TCP 连接时需要客户端和服务器端总共发送三个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发。

下面来看看三次握手的流程图:

  • 第一次握手:客户端将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给服务器端,客户端进入SYN_SENT状态,等待服务器端确认。
  • 第二次握手:服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将标志位SYN和ACK都置为1,且设置ack=J+1,随机产生一个值seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD状态。
  • 第三次握手:客户端收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。
四次挥手
  • 四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。

  • 中断连接端可以是客户端,也可以是服务器端。

  • 第一次挥手:客户端发送一个FIN=M,用来关闭客户端到服务器端的数据传送,客户端进入FIN_WAIT_1状态。意思是说"我客户端没有数据要发给你了",但是如果你服务器端还有数据没有发送完成,则不必急着关闭连接,可以继续发送数据。

  • 第二次挥手:服务器端收到FIN后,先发送ack=M+1,告诉客户端,你的请求我收到了,但是我还没准备好,请继续你等我的消息。这个时候客户端就进入FIN_WAIT_2 状态,继续等待服务器端的FIN报文。

  • 第三次挥手:当服务器端确定数据已发送完成,则向客户端发送FIN=N报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。服务器端进入LAST_ACK状态。

  • 第四次挥手:客户端收到FIN=N报文后,就知道可以关闭连接了,但是他还是不相信网络,怕服务器端不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果Server端没有收到ack则可以重传。服务器端收到ACK后,就知道可以断开连接了。客户端等待了2MSL(大概4分钟)后依然没有收到回复,则证明服务器端已正常关闭,那好,我客户端也可以关闭连接了。最终完成了四次挥手。

TCP和UDP的应用场景
  • TCP应用场景
    • 效率要求相对低,但对准确性要求相对高的场景,因为传输中需要对数据进行确认,重发,排序等操作,效率没有udp高
    • 文件传输:FTP\HTTP对数据的准确性要求高,速度可以相对慢
    • 发送或接收邮件:POP3\IMAP\SMTP对数据准确性要求高,非紧急应用
    • 远程登陆:TELNET\SSH对数据准确性有一定要求,有连接概念
  • UCP应用场景
    • 即时通信:QQ聊天,对数据准确性和丢包要求比较低,但速度必须快
    • 在线视频:RTSP速度一定要快,保证视频连续,但是偶尔花了一个图像帧,还是可以接受的
    • 网络语音电话:VoIP数据包一般比较小,需要高速发送,偶尔断音或串音也没有问题
Socket概念
  • 通俗理解
    • 人们经常把socket翻译为套接字,socket其实就是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信。
    • 其实socket就是一个Python中的一个模块。我们通过调用模块中已经实现的方法建立两个进程/应用之间的连接和通信。
TCP协议下的Socket

注意:socket绑定IP和端口时可能出现下面的问题:

解决办法:

#加入一条socket配置,重用ip和端口
import socket
from socket import SOL_SOCKET,SO_REUSEADDR
sk = socket.socket()
sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) #在bind前加,允许地址重用
sk.bind(('127.0.0.1',8898))  #把地址绑定到套接字

但是如果你加上了上面的代码之后还是出现这个问题:OSError: [WinError 10013] 以一种访问权限不允许的方式做了一个访问套接字的尝试。那么只能换端口了,因为你的电脑不支持端口重用。

尝试不间断的让客户端和服务端进行数据交互

你会发现,第一个连接的客户端可以和服务端收发消息,但是第二个连接的客户端发消息服务端是收不到的.

原因就是:tcp属于长连接,长连接就是一直占用着这个链接,这个连接的端口被占用了,第二个客户端过来连接的时候,他是可以连接的,但是处于一个占线的状态,就只能等着去跟服务端建立连接,除非一个客户端断开了(优雅的断开可以,如果是强制断开就会报错,因为服务端的程序还在第一个循环里面),然后就可以进行和服务端的通信了。什么是优雅的断开呢?看代码:

UDP协议下的Socket

基于UDP的socket通讯流程:

服务器端先初始化Socket,然后与端口绑定(bind),recvform接收消息,这个消息有两项,消息内容和对方客户端的地址,然后回复消息时也要带着你收到的这个客户端的地址,发送回去,最后关闭连接,一次交互结束。


- Socket是一种特殊的I/O,常用的Socket类型有两种: 
  -  流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用。
    - SOCK_STREAM   是有保障的(即能保证数据正确传送到对方)面向连接的SOCKET,多用于资料(如文件)传送。
    - SOCK_DGRAM   是无保障的面向消息的socket , 主要用于在网络上发广播信息。




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值