专栏首页技术探究-前端、Python、爬虫、数据分析、工具19 Python 基础: 重点知识点--网络通信基础知识讲解

19 Python 基础: 重点知识点--网络通信基础知识讲解

前言

其他文章均已发表,可通过 “技术专栏 -- Python -- PY基础” 进行阅读。

这是 “Python 基础”系列的第 19 篇文章 ,共 20 篇 。 01 Python 基础:Python入门必看之语法基础 02 Python 基础:列表及字典内置函数&方法内容梳理 03 Python 基础:Python函数及递归函数知识点梳理 04 Python 基础:讲解迭代、过滤、匿名函数、排序算法四大知识点 05 Python 基础:高阶函数学习实践 06 Python 基础:难点装饰器的学习介绍及实现赌博收益小案例 07 Python 基础:重点知识点函数的参数难点解答 08 Python 基础:面试问你类与实例及其属性还不会吗 09 Python 基础:手把手带你梳理对象、继承与多态知识点 10 Python 基础:如何定制类,这里有答案 11 Python 基础:知识巩固,实现一个简易学生管理系统 12 Python 基础:如何优化代码质量,错误、调试和测试你必须要懂 13 Python 基础:模块的概念及使用方法并着重介绍两个常用模块 14 Python 基础:重点知识点--IO编程 15 Python 基础:程序猿必懂知识之正则表达式 16 Python 基础:重点知识点--Pygame的基础知识梳理 17 Python 基础:重点知识点--Pygame实现儿时经典游戏坦克大战 18 Python 基础:重点知识点--进程和线程概念、应用知识梳理 19 Python 基础:重点知识点--网络通信基础知识讲解 20 Python 基础:重点知识点--网络通信进阶知识讲解

目录

19 Python 基础: 重点知识点--网络通信基础知识讲解,共有 5 部分:

  • 网络通信--网络通信概述
  • 网络通信--IP
  • 网络通信--socket
  • 网络通信--UDP网络程序
  • 网络通信--TCP编程

网络通信--网络通信概述

概述

美国国防部认为,如果仅有一个集中的军事指挥中心,万一这个中心被原苏联的核武器摧毁。全国的军事指挥将处于瘫痪状态,其后果将不堪设想,因此有必要设计这样一个分散的指挥系统──它必须由一个个分散的指挥点组成,当部分指挥点被摧毁后其它点仍能正常工作,而这些分散的点又能通过某种形式的通讯网取得联系。

1969年,美国国防部高级研究计划管理局( ARPA - - Advanced Research Projects Agency )开始建立一个命名为ARPAnet的网络, 把美国的几个军事及研究用电脑主机联接起来。当初,ARPAnet只联结4台主机,从军事要求上是置于美国国防部高级机密的保护之下,从技术上它还不具备向外推广的条件。Internet。

1986年,美国国家科学基金会(National Science Foundation,NSF)利用ARPAnet发展出来的TCP/IP通讯协议,在5 个科研教育服务超级电脑中心的基础上建立了NSFnet广域网。由于美国国家科学基金会的鼓励和资助,很多大学、政府资助的研究机构甚至私营的研究机构纷纷把自己的局域网并入NSFnet中。那时,ARPAnet 的军用部分已脱离母网,建立自己的网络--Milnet。ARPAnet --网络之父,逐步被NSFnet所替代。到1990年, ARPAnet已退出了历史舞台。如今,NSFnet已成为Internet的重要骨干网之一。

1989年,由CERN开发成功WWW,为Internet 实现广域超媒体信息截取/检索奠定了基础。

在90年代以前,Internet的使用一直仅限于研究与学术领域,商业性机构进入Internet一直受到这样或那样的法规或传统问题的困扰。事实上,象美国国家科学基金会等曾经出资建造Internet的政府机构对Internet上的商业活动并不感兴趣。

tcp/ip简介

image.png

作为新时代标杆的我们,已经离不开手机、离不开网络,对于互联网大家可能耳熟能详,但是计算机网络的出现比互联网要早很多

1. 什么是协议

有的说英语,有的说中文,有的说德语,说同一种语言的人可以交流,不同的语言之间就不行了

为了解决不同种族人之间的语言沟通障碍,现规定国际通用语言是英语,这就是一个规定,这就是协议

2. 计算机网络沟通用什么

现在的生活中,不同的计算机只需要能够联网(有线无线都可以)那么就可以相互进行传递数据

那么不同种类之间的计算机到底是怎么进行数据传递的呢?

就像说不同语言的人沟通一样,只要有一种大家都认可都遵守的协议即可,那么这个计算机都遵守的网络通信协议叫做TCP/IP协议

3. TCP/IP协议(族)

早期的计算机网络,都是由各厂商自己规定一套协议,IBM、Apple和Microsoft都有各自的网络协议,互不兼容

为了把全世界的所有不同类型的计算机都连接起来,就必须规定一套全球通用的协议,为了实现互联网这个目标,互联网协议簇(Internet Protocol Suite)就是通用协议标准。

因为互联网协议包含了上百种协议标准,但是最重要的两个协议是TCP和IP协议,所以,大家把互联网的协议简称TCP/IP协议

常用的网络协议如下图所示:

说明:

  • 网际层也称为:网络层
  • 网络接口层也称为:链路层

端口

1. 什么是端口

那么TCP/IP协议中的端口指的是什么呢?

端口就好一个房子的门,是出入这间房子的必经之路。

如果一个进程需要收发网络数据,那么就需要有这样的端口

在linux系统中,端口可以有65536(2的16次方)个之多!

既然有这么多,操作系统为了统一管理,所以进行了编号,这就是端口号

2. 端口号

端口是通过端口号来标记的,端口号只有整数,范围是从0到65535

3. 端口是怎样分配的

端口号不是随意使用的,而是按照一定的规定进行分配。

端口的分类标准有好几种,我们这里不做详细讲解,只介绍一下知名端口和动态端口

3.1 知名端口(Well Known Ports)

知名端口是众所周知的端口号,范围从0到1023

80端口分配给HTTP服务 21端口分配给FTP服务 可以理解为,一些常用的功能使用的号码是估计的,好比 电话号码110、10086、10010一样

一般情况下,如果一个程序需要使用知名端口的需要有root权限

3.2 动态端口(Dynamic Ports)

动态端口的范围是从1024到65535

之所以称为动态端口,是因为它一般不固定分配某种服务,而是动态分配。

动态分配是指当一个系统进程或应用程序进程需要网络通信时,它向主机申请一个端口,主机从可用的端口号中分配一个供它使用。

当这个进程关闭时,同时也就释放了所占用的端口号。

3.3 怎样查看端口?

用“netstat -an”查看端口状态

4. 小总结

端口有什么用呢 ?我们知道,一台拥有IP地址的主机可以提供许多服务,比如HTTP(万维网服务)、FTP(文件传输)、SMTP(电子邮件)等,这些服务完全可以通过1个IP地址来实现。那么,主机是怎样区分不同的网络服务呢?显然不能只靠IP地址,因为IP地址与网络服务的关系是一对多的关系。实际上是通过“IP地址+端口号”来区分不同的服务的。需要注意的是,端口并不是一一对应的。比如你的电脑作为客户机访问一台WWW服务器时,WWW服务器使用“80”端口与你的电脑通信,但你的电脑则可能使用“3457”这样的端口。

网络通信--IP

ip地址

1. 什么是地址

地址就是用来标记地点的

2. ip地址的作用

ip地址:用来在网络中标记一台电脑的一串数字,比如192.168.1.1;在本地局域网上是惟一的。

3. ip地址的分类

每一个IP地址包括两部分:网络地址和主机地址

3.1 A类IP地址

一个A类IP地址由1字节的网络地址和3字节主机地址组成,网络地址的最高位必须是“0”,

地址范围1.0.0.1-126.255.255.254

二进制表示为:00000001 00000000 00000000 00000001 - 01111110 11111111 11111111 11111110

可用的A类网络有126个,每个网络能容纳1677214个主机

3.2 B类IP地址

一个B类IP地址由2个字节的网络地址和2个字节的主机地址组成,网络地址的最高位必须是“10”,

地址范围128.1.0.1-191.255.255.254

二进制表示为:10000000 00000001 00000000 00000001 - 10111111 11111111 11111111 11111110

可用的B类网络有16384个,每个网络能容纳65534主机

3.3 C类IP地址

一个C类IP地址由3字节的网络地址和1字节的主机地址组成,网络地址的最高位必须是“110”

范围192.0.1.1-223.255.255.254

二进制表示为: 11000000 00000000 00000001 00000001 - 11011111 11111111 11111110 11111110

C类网络可达2097152个,每个网络能容纳254个主机

3.4 D类地址用于多点广播

D类IP地址第一个字节以“1110”开始,它是一个专门保留的地址。

它并不指向特定的网络,目前这一类地址被用在多点广播(Multicast)中

多点广播地址用来一次寻址一组计算机

地址范围224.0.0.1-239.255.255.254

3.5 E类IP地址

以“1111”开始,为将来使用保留

E类地址保留,仅作实验和开发用

3.6 私有ip

在这么多网络IP中,国际规定有一部分IP地址是用于我们的局域网使用,也就

是属于私网IP,不在公网中使用的,它们的范围是:

10.0.0.0~10.255.255.255

172.16.0.0~172.31.255.255

192.168.0.0~192.168.255.255

3.7 注意

IP地址127.0.0.1~127.255.255.255用于回路测试,

如:127.0.0.1可以代表本机IP地址,用http://127.0.0.1就可以测试本机中配置的Web服务器。

网络通信--socket

socket简介

  1. 本地的进程间通信(IPC)有很多种方式,例如 队列 同步(互斥锁、条件变量等) 以上通信方式都是在一台机器上不同进程之间的通信方式,那么问题来了

网络中进程之间如何通信?

2. 网络中进程之间如何通信

首要解决的问题是如何唯一标识一个进程,否则通信无从谈起!

在本地可以通过进程PID来唯一标识一个进程,但是在网络中这是行不通的。

其实TCP/IP协议族已经帮我们解决了这个问题,网络层的“ip地址”可以唯一标识网络中的主机,而传输层的“协议+端口”可以唯一标识主机中的应用程序(进程)。

这样利用ip地址,协议,端口就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互

3. 什么是socket

socket(简称 套接字) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:

它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的

例如我们每天浏览网页、QQ 聊天、收发 email 等等

4. 创建socket

在 Python 中 使用socket 模块的函数 socket 就可以完成:

socket.socket(AddressFamily, Type) 说明:函数 socket.socket 创建一个 socket,返回该 socket 的描述符,该函数带有两个参数:

Address Family:可以选择 AF_INET(用于 Internet 进程间通信) 或者 AF_UNIX(用于同一台机器进程间通信),实际工作中常用AF_INET Type:套接字类型,可以是 SOCK_STREAM(流式套接字,主要用于 TCP 协议)或者 SOCK_DGRAM(数据报套接字,主要用于 UDP 协议)

image.png

网络通信--UDP网络程序

UDP介绍

UDP --- 用户数据报协议,是一个无连接的简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

UDP是一种面向无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

UDP特点:

UDP是面向无连接的通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。UDP传输数据时有大小限制,每个被传输的数据包必须限定在64KB之内。UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。

【适用情况】

UDP是面向消息的协议,通信时不需要建立连接,数据的传输自然是不可靠的,UDP一般用于多点通信和实时的数据业务,比如

  • 语音广播
  • 视频
  • QQ
  • TFTP(简单文件传送)
  • SNMP(简单网络管理协议)
  • RIP(路由信息协议,如报告股票市场,航空信息)
  • DNS(域名解释)
  • 注重速度流畅

UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序。例如视频会议系统,并不要求音频视频数据绝对的正确,只要保证连贯性就可以了,这种情况下显然使用UDP会更合理一些。

创建一个udp客户端程序的流程是简单,具体步骤如下:

  • 创建客户端套接字
  • 发送/接收数据
  • 关闭套接字

| 下面测试与调试需要用到一个软件,网络调试工具NetAssist.exe(自行百度下载即可): |

| ------------------------------------------------------------ |

| 1.接受信息或则发送消息出去,设置好网络协议、本地ip地址与本地端口号连接即可 |

| 2.设置端口号,是用于接受信息的识别,就是这软件对外的端口号是多少,别人才能把信息发到你软件上 |

| 3.设置端口号时,有可能出现端口号已被其他程序占用,所以连接不了,此时更换端口号即可 |

#coding=utf-8
#实现udp套接字发送数据出去到对应ip地址与端口号上

from socket import *

#1. 创建套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)#SOCK_DGRAM表示UDP协议,AF_INET表示ipv4协议,基本都是这个的ipv4

#2. 准备接收方的地址

sendAddr = ('192.168.8.213', 7777)

#3. 从键盘获取数据
sendData = input("请输入要发送的数据:")

#4. 发送数据到指定的电脑上,实例化udpSocket中有个sengto方法
#第一个参数是二进制对象,要将字符串转换为二进制对象,需要使用encode方法,根据对方接收什么编码,进行解码。
udpSocket.sendto(sendData.encode('gbk'), sendAddr)

#5. 关闭套接字
udpSocket.close()

image.png

image.png

##创建udp网络程序-接收数据
#coding=utf-8

from socket import *

#1. 创建套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)

#2. 准备接收方的地址
sendAddr = ('192.168.8.213', 7777)

#3. 从键盘获取数据
sendData = input("请输入要发送的数据:")

#4. 发送数据到指定的电脑上
udpSocket.sendto(sendData.encode('gbk'), sendAddr)

#5. 等待接收对方发送的数据
recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最大字节数

#6. 显示对方发送的数据
# print(recvData),打印出来可以得到他是一个元组,所以下面写为打印更加详细具体
#将二进制对象转为字符串,这个时候用decode(),根据对方用什么编码,你就用什么解码
print('发送方%s,端口号%s:%s'%(recvData[1][0],recvData[1][1],recvData[0].decode('gbk')))

#7. 关闭套接字
udpSocket.close()

image.png

image.png

image.png

#udp绑定端口号
#coding=utf-8

from socket import *

#1. 创建套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)

#2. 绑定本地的相关信息,如果一个网络程序不绑定,则系统会随机分配

bindAddr = ('', 6666) # ip地址和端口号,ip一般不用写,表示本机的任何一个ip

udpSocket.bind(bindAddr)

n = 10
while n>0:
    #3. 等待接收对方发送的数据
    recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最大字节数

    #4. 显示接收到的数据
    print('发送方%s,端口号%s:%s'%(recvData[1][0],recvData[1][1],recvData[0].decode('gbk')))
    n= n-1

#5. 关闭套接字
udpSocket.close()

image.png

同时运行下面两个就可以实现一个发送一个接收,打开两个进程同时

#循环发送
#coding=utf-8

from socket import *

#1. 创建套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)#UDP协议

#2. 准备接收方的地址

sendAddr = ('192.168.8.213', 6666)
bindAddr = ('', 7777) # ip地址和端口号,ip一般不用写,表示本机的任何一个ip
#发送方也可以绑定
udpSocket.bind(bindAddr)


while True:
    #3. 从键盘获取数据
    sendData = input("请输入要发送的数据:")

    #4. 发送数据到指定的电脑上
    #第一个参数是二进制对象,要将字符串转换为二进制对象,需要使用encode方法,根据对方接收什么编码,进行解码。
    udpSocket.sendto(sendData.encode('gbk'), sendAddr)
    recvData = udpSocket.recvfrom(1024)
    print('发送方%s,端口号%s:%s'%(recvData[1][0],recvData[1][1],recvData[0].decode('gbk')))

#5. 关闭套接字
udpSocket.close()

image.png

#udp绑定端口号
#coding=utf-8

from socket import *

#1. 创建套接字
udpSocket = socket(AF_INET, SOCK_DGRAM)

#2. 绑定本地的相关信息,如果一个网络程序不绑定,则系统会随机分配

bindAddr = ('', 6666) # ip地址和端口号,ip一般不用写,表示本机的任何一个ip

udpSocket.bind(bindAddr)

n = 10
while n>0:
    #3. 等待接收对方发送的数据
    recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最大字节数

    #4. 显示接收到的数据
    print('发送方%s,端口号%s:%s'%(recvData[1][0],recvData[1][1],recvData[0].decode('gbk')))
    s = '服务器已收到了:%s'%recvData[0].decode('gbk')
    print( type(recvData[1][0]))
    print(recvData[1][1])
    udpSocket.sendto(s.encode('gbk'),(recvData[1][0],recvData[1][1]))
    n= n-1

#5. 关闭套接字
udpSocket.close()

image.png

image.png

image.png

网络通信--TCP编程

udp通信模型

udp通信模型中,在通信开始之前,不需要建立相关的链接,只需要发送数据即可,类似于生活中,"写信""

image.png

tcp通信模型

tcp通信模型中,在通信开始之前,一定要先建立相关的链接,才能发送数据,类似于生活中,"打电话""

image.png

image.png

tcp服务器

案例:生活中的电话机

如果想让别人能更够打通咱们的电话获取相应服务的话,需要做一下几件事情:

  1. 买个手机
  2. 插上手机卡
  3. 设计手机为正常接听状态(即能够响铃)
  4. 静静的等着别人拨打

tcp服务器:如同上面的电话机过程一样,在程序中,如果想要完成一个tcp服务器的功能,需要的流程如下:

  1. socket创建一个套接字
  2. bind绑定ip和port
  3. listen使套接字变为可以被动链接
  4. accept等待客户端的链接
  5. recv/send接收发送数据 一个很简单的tcp服务器如下:
#coding=utf-8from socket import *# 创建TCPsocket服务器,socket的第二个参数,sock_stream,   %%SOCK_DGRAM表示UDP协议%%tcpSerSocket = socket(AF_INET, SOCK_STREAM)
# 绑定本地信息address = ('192.168.132.1', 6777)tcpSerSocket.bind(address)# tcpSerSocket.bind(('',7788))# 使用socket创建的套接字默认的属性是主动的,使用listen将其变为被动的,这样就可以接收别人的链接了
tcpSerSocket.listen(5)       # 数字表示最多同时连接或接受多少个用户链接,最大可连接客户端数# 如果有新的客户端来链接服务器,那么就产生一个新的套接字专门为这个客户端服务器
# newSocket用来为这个客户端服务
# tcpSerSocket就可以省下来专门等待其他新客户端的链接#新端口连接好了,你要获取这个连接的管道,那么你需要解构accept的返回值print('-----等待客户端连接进来-----')newSocket, clientAddr = tcpSerSocket.accept()print(newSocket)print(clientAddr)print('-----客户端已连接进来')
# 接收对方发送过来的数据,最大接收1024个字节print('-----等待获取客户端的消息-----')recvData = newSocket.recv(1024)print ('接收到的数据为:',recvData.decode('gbk'))
# 发送一些数据到客户端newSocket.send(b"thank you !")
# 关闭为这个客户端服务的套接字,只要关闭了,就意味着为不能再为这个客户端服务了,如果还需要服务,只能再次重新连接newSocket.close()# 关闭监听套接字,只要这个套接字关闭了,就意味着整个程序不能再接收任何新的客户端的连接tcpSerSocket.close()

image.png

image.png

image.png

tcp客户端

tcp客户端,并不是像之前一个段子:一个顾客去饭馆吃饭,这个顾客要点菜,就问服务员咱们饭店有客户端么,然后这个服务员非常客气的说道:先生 我们饭店不用客户端,我们直接送到您的餐桌上.

如果,不学习网络的知识是不是 说不定也会发生那样的笑话 ,哈哈.

所谓的服务器端:就是提供服务的一方,而客户端,就是需要被服务的一方.

tcp客户端构建流程

tcp的客户端要比服务器端简单很多,如果说服务器端是需要自己买手机、查手机卡、设置铃声、等待别人打电话流程的话,那么客户端就只需要找一个电话亭,拿起电话拨打即可,流程要少很多.

#coding=utf-8
from socket import *

# 创建socket,Tcpshock创建
tcpClientSocket = socket(AF_INET, SOCK_STREAM)

# 链接服务器
serAddr = ('192.168.132.1', 6777)
#请输入服务端的IP地址
# serverIp = input('请输入服务端的IP地址:')
# serverPort = int(input('请输入服务器的端口号:'))

# serAddr = (serverIp,serverPort)
#拨打电话,连接服务端
tcpClientSocket.connect(serAddr)

# 提示用户输入数据
sendData = input("请输入要发送的数据:")

tcpClientSocket.send(sendData.encode('gbk'))

# 接收对方发送过来的数据,最大接收1024个字节
recvData = tcpClientSocket.recv(1024)
print ('接收到的数据为:',recvData.decode('gbk'))

# 关闭套接字,挂电话
tcpClientSocket.close()

image.png

应用:模拟QQ聊天

客户端

fromsocketimport*

#创建socket
tcpClientSocket=socket(AF_INET,SOCK_STREAM)

#链接服务器,设定ip地址与端口号
serAdrr=('192.168.8.187',7788)
tcpClientSocket.connect(serAdrr)

whileTrue:

#提醒用户输入数据:
sendData=input('send:')

ifsendData=='exitServer':
print('退出连接')
break
eliflen(sendData)>0:
tcpClientSocket.send(sendData.encode('gbk'))
else:
print('退出连接')
break

#接受对方发送数据,最大为1024个字节
recvData=tcpClientSocket.recv(1024)
print('recv:',recvData.decode('gbk'))

#关闭套接字
tcpClientSocket.close()

服务器端

#coding=utf-8
fromsocketimport*

#创建socket
tcpSerSocket=socket(AF_INET,SOCK_STREAM)

#绑定本地信息
address=('',7788)
tcpSerSocket.bind(address)

#使用socket创建的套接字默认的属性是主动的,使用listen将其变为被动的,这样就可以接收别人的链接了
tcpSerSocket.listen(5)

whileTrue:
#一个循环服务1个客户
#如果有新的客户端来链接服务器,那么就产生一个信心的套接字专门为这个客户端服务器
#newSocket用来为这个客户端服务
#tcpSerSocket就可以省下来专门等待其他新客户端的链接
print('------等待客户连接------')
newSocket,clientAddr=tcpSerSocket.accept()
print('------新客户已连接')
whileTrue:

#接收对方发送过来的数据,最大接收1024个字节
recvData=newSocket.recv(1024)
print(recvData)
#如果接收的数据的长度为0,则意味着客户端关闭了链接
ifrecvData==b'exitserver':
print('客户已完成服务,退出')
break
eliflen(recvData)>0:
print('recv:',recvData.decode('gbk'))
else:
print('客户已完成服务,退出')
break


#发送一些数据到客户端
#sendData=input("send:")
sendDate='服务端已收信息:%s'%recvData.decode('gbk')
newSocket.send(sendDate.encode('gbk'))

#关闭为这个客户端服务的套接字,只要关闭了,就意味着为不能再为这个客户端服务了,如果还需要服务,只能再次重新连接
newSocket.close()

#关闭监听套接字,只要这个套接字关闭了,就意味着整个程序不能再接收任何新的客户端的连接
tcpSerSocket.close()

本文分享自微信公众号 - 离不开的网(Gy_dxj)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 19 Python 基础: 重点知识点--网络通信基础知识讲解.md

    本文首发于腾讯云+社区,也可关注微信公众号【离不开的网】支持一下,就差你的关注支持了。

    小Gy
  • 12 Python 基础: 如何优化代码质量,错误、调试和测试你必须要懂.md

    有的错误是程序编写有问题造成的,比如本来应该输出整数结果输出了字符串,这种错误我们通常称之为bug,bug是必须修复的。

    小Gy
  • 一个案例让你入门爬虫之三:Q房网房源图片下载及多线程爬虫实现实例

    本篇是一个案例让你入门爬虫的最后一篇,在本篇中将简单的带你实现图片的下载以及加快爬取效率,使用多线程爬虫。

    小Gy
  • 19 Python 基础: 重点知识点--网络通信基础知识讲解.md

    本文首发于腾讯云+社区,也可关注微信公众号【离不开的网】支持一下,就差你的关注支持了。

    小Gy
  • 基于 Java 实现的人脸识别功能(附源码)

    人脸识别技术是很复杂的,自己用Java手撕一个识别算法有点不切实际,毕竟实力不允许我这么嚣张,还是借助三方的SDK吧!

    程序员内点事
  • 为了宠粉,用 Java 实现人脸识别功能(附源码)

    远程在家办公的第N天,快要闲出屁了,今天突然有个小学弟加我VX说要咨询我点技术问题(终于可以装X了)。 看了他的需求描述,大概是要做一个Java web版本的人...

    程序员内点事
  • CMake与Make

    但如果源文件太多,一个一个编译时就会特别麻烦,于是人们想到,为什么不设计一种类似批处理的程序,来批处理编译源文件呢,于是就有了make工具,它是一个自动化编译...

    bear_fish
  • 考研英语-1-导学

    英二图表作文要重视。总体而言,英语一会比英语二难点。不过就写作而言,英语二会比英语一有难度,毕竟图表作文并不好写。

    用户1335799
  • 瞎忙族与高效人士的13个不同点

    用户1756920
  • 定制nginx Dockerfile 支持lua环境,k8s虚拟化基础

    FROM centos:7.7.1908 MAINTAINER zhangdd LABEL Description=”基于CentOS 7,安装nginx-...

    zhangdd

扫码关注云+社区

领取腾讯云代金券