一、网络编程
1.概念
1.1计算机网络
就是把分布在不同区域的计算机与专门的外部设备用通信线路相互之间连接起来,组成一个功能强大,规模比较大的网络系统
作用:使得计算机之间可以进行消息的传递,数据的共享
1.2网络编程
指的是在同一个网络中不同的计算机之间的通信
2.计算机之间通信需要的条件
计算机之间通讯的必要条件:ip地址,端口,协议
2.1ip地址
1>概念
ip地址指的是互联网协议地址【Internet Protocol Address】
作用:是联网设备和互联网之间的唯一标识,在同一个网段中,ip地址是唯一的
2>组成
ip地址是数字型的,是一个32位整数,为了便于记忆,将32位整数分为4个8位二进制,每8位用圆点隔开,将每个8位的二进制转换为0~255之间的十进制,通常见到的ip地址的形式:192.169.xx.xx
3>分类
形式分类:
ipv4:ip地址由4个字节组成,分为4段
ipv6:ip地址由6个字节组成,分为6段
功能分类:
A类:保留给政府机构,1.0.0.1~126.255.255.254
B类:分配给中型企业,128~191
C类:分配给任何需要的个人,192~223
D类:用于组播,224~239【组播是一种数据的传输方式】
E类:用于实验,240~255
127.0.0.1:回送地址,一般指的是本机的ip,可以使用localhost表示,一般用于测试
总结;ip地址可以唯一的确定网络上的一个通信实体,但是一个通信实体可以有多个通信程序可以同时提供网络服务,还需要端口
2.2端口
1>概念
数据的发送和接收都需要通过端口进出计算机,端口号用于唯一标记通信实体上进行网络通信的程序
注意:同一台机器上不能两个程序同时占用同一个端口,端口号的取值范围:0~65535
2>分类
a.公认端口:0~1023 ,一些特殊的应用
b.注册端口:1025~49151
c.动态端口或者私有端口:1024~65535
3>常用端口
mysql:3306
oracle:1521
tomcat:8080
qq:4000
2.3网络协议
规定一套全球通用的协议
作用:连接网络的网络协议
TCP:
UDP
HTTP/HTTPS
3.TCP/IP协议
互联网协议简称为TCP/IP协议
解释:通信的时候,双方必须知道对方的标记,互联网上每个计算机的唯一标识就是ip地址,如果一台计算机同时接入到两个或者更多的网络,比如路由器,他就会有 两个或者多个ip地址,所以,ip地址对应的实际上是计算机的网络接口,通常是网卡
特点:不安全,数据按块发送,途径多个路由,但不保证数据能够顺利到达,或者不保证对方接受到的数据是完整的
4.TCP编程【掌握】
4.1tcp概念
Socket:套接字,应用程序通常需要通过套接字向网络发出请求或者应答网络请求,使得主机或者一台计算机的进程间可以通信
Socket是网络编程中的一个抽象概念,通常使用Socket表示打开了一个网络连接,打开一个Socket需要知道目标计算机的ip地址,端口号,指定协议
TCP:Transmission Control Protocol ,传输控制协议,基于字节流的传输层通信协议
特点:
a.安全的【确保接收方完全正确的接收到消息】
b.面向连接的【面向连接的协议,发送消息之前,需要建立连接,所以TCP需要耗费时间】
c.数据传输的效率比较低
d.一旦双方建立连接,可以按照统一的格式传输数据,数据的大小是没有限制的
使用经典的三次握手建立连接
a.客户端向服务端发起请求:第一次握手
b.服务端收到请求之后,回客户端一个响应:第二次握手
c.客户端收到服务端的响应之后,回给服务端一个确认信息:第三次握手
注意:使用tcp来实现数据的传输需要有发送方和接收方,但是两个通信实体之间并没有严格的客户端和服务端之分,在两个通信实体进行通信之前,必须有一个通信实体做出主动姿态,主动发起连接请求
4.2socket通信流程
创建tcp连接时,主动发起请求的叫做客户端,被动接受请求的叫做服务端
4.3tcp编程
流程
client.py
#发送方【客户端】 import socket #1.客户端创建socket client = socket.socket() #2.客户端打开socket,根据服务端的ip地址和端口号试图连接服务端的socket """ connet(元组) 元组:ip地址和端口 """ client.connect(("10.12.153.31",8888)) #3.客户端向服务端发送消息【客户端向socket写入信息】 """ sendall(string,flag) string:将要发送给服务端的数据,注意:需要将字符串类型转换为字节类型 工作原理:内部通过递归调用send,将所有的内容全部发送出去 返回值:成功则返回None,失败则会抛出异常 """ client.sendall(bytes("Python1804你好",encoding="utf-8")) #bytes #4.关闭socket client.close()
server.py
#接收方【服务端】 import socket #服务端流程描述 #1.创建socket对象 #根据地址类型,socket类型,协议创建socket server = socket.socket() #2.服务端为socket绑定ip地址和端口号 #bind(元组):将IP地址和端口绑定到指定socket上,ip地址和端口号以元组的形式传参 #注意8888表示的是服务端的端口,客户端的端口系统自动分配 ip_port = ("10.12.153.31",8888) server.bind(ip_port) #3.服务端socket监听端口号请求,随时准备接受客户端发来的连接 #注意:此时,只是在监听,服务器的socket并没有被打开 """ listen(backlog) 开始监听传入的连接,backlog指定在拒绝连接之前,可以挂起的最大的连接数量 backlog等于5,表示内核已经连接到了请求,但是服务器还没有调用accept进行处理 注意:backlog不能无限大,因为在内核中需要维持连接队列 """ server.listen(5) #问题:代码执行到listen,会产生阻塞,直到有客户端连接到服务端 print("server waiting.......") #4.接收客户端发来的请求 """ accept():服务端socket接收客户端的socket请求,服务端socket是被动打开的,开始接收客户端的请求 直到客户端返回连接信息【三次握手】,此时,socket会进入阻塞状态, accept函数会一直等待客户端返回连接信息,开始接收下一个客户端的请求 返回值:(conn,addr):其中conn代表是连接到的客户端对象,可以接收和发送数据,addr代表的是连接到的客户端的地址 """ conn,addr = server.accept() #5.接收客户端的消息 """ recv(字节数):接收套接字的数据,返回值为字符串,注意:接收到的数据为字节类型,所以为了能够识别,需要转换为字符串 """ client_data = conn.recv(1024) print("客户端%s发来的消息:%s" %(addr,str(client_data,"utf-8"))) #6.关闭socket server.close()
循环发送数据和接收数据
server.py
import socket server = socket.socket() server.bind(("10.12.153.31",9999)) server.listen(5) print("服务端启动成功") clientSocket,clientAddress = server.accept() print("%s-----%s连接成功" %(str(clientSocket),clientAddress)) while True: #接收客户端发来的内容 data = clientSocket.recv(1024) #将字节类型转换为字符串类型:解码 print("客户端说:" + data.decode("utf-8")) sendData = input("请输入要回复给客户端的内容:") clientSocket.send(sendData.encode("utf-8")) if data.decode("utf-8") == "bye" or data.decode("utf-8") == "再见": break
client.py
import socket client = socket.socket() client.connect(("10.12.153.31",9999)) while True: #发送 data = input("请输入要发送给服务端的内容:") #将字符串转换为字节类型:编码 client.send(data.encode("utf-8")) #接收 info = client.recv(1024) print("服务端说:" + info.decode("utf-8")) if data == "bye" or data == "再见" or info.decode("utf-8") == "bye": break
5.UDP编程
【面试题:tcp和udp之间的区别】
User Datagram Protocol,用户数据包协议,提供面向事务的简单不可靠的信息传送
特点:
a.不安全的【发送方所发送的数据包并不一定以相同的次序到达接收方,或者接收方不一定能够接收到】,比如:飞秋
b.无连接的【每个数据包【报】中给出了完整的地址信息,因此无需建立发送方和接收方之间的连接】
c.效率高,速度快
d.传输的数据有大小限制,每个被传输的数据包必须限定在64k以内
代码演示:
server.py
import socket #创建socket对象 server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #绑定ip地址和端口号 server.bind(("10.12.153.31",6666)) #接收数据 data,addr = server.recvfrom(1024) print("客户端说:" + data.decode("utf-8"))
client.py
import socket client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) #发送数据 data = input("请输入要发送的数据:") client.sendto(data.encode("utf-8"),("10.12.153.31",6666))
总结:
a.对于客户端,要主动连接服务端的ip地址和端口号,对于服务端,首先要监听指定端口,然后,对每一个新的连接,创建一个线程或者一个进程来处理,通常,服务端会无限的运行下去
b.同一个端口,被一个socket绑定之后,就不能绑定其他的socket了
c.tcp连接创建的是双向通道,双方都可以给对方发送消息,也可以接受对方的消息
d.HTTP/HTTPS:被动协议,只有客户端做出一个主动姿态,主动发起请求,服务端才会做出一个响应
二、反射【扩展】
1.概念
通过字符串操作对象中的字段
反射就是通过字符串的形式,导入模块,到模块中寻找函数并执行,到对象中操作【查找,获取。删除,添加】成员
是一种基于字符串的事件驱动
代码演示:
class Person(object): num = 10 def __init__(self,name,age): self.name = name self.__age = age def show(self): print("show") @classmethod def check(cls): print("check") #创建一个Person对象 p = Person("杨阳",20) print(p.name) """ p.name;name本质上是一个变量 name字段可以是一个字符串码? p."name"---->不对,因为name是一个变量,并不是一个字符串 思考问题:如果有一个字符串"name",获取lisi """ #1.getattr(obj,name,default) attribute;属性 #作用:获取某个对象的属性值 #参数:指明对象,获取对象的属性的名字【使用字符串表示】,默认值【如果该字段名不存在,则使用默认值】 value = getattr(p,"name1","瘦子") print(value) #如果实例属性被私有化,通过反射如何获取 #print(p.__age) print(p._Person__age) value1 = getattr(p,"_Person__age",10) print(value1) #20 #2.通过getattr获取函数 func = getattr(p,"show") #func = show print(func) func() #获取类方法,obj可以是对象,也可以是类名 #类方法的特点:可以使用类名调用,也可以使用对象调用 func1 = getattr(p,"check") func1() func1 = getattr(Person,"check") func1() #获取类属性,obj可以是对象,也可以是类名 n1 = getattr(p,"num") print(n1) n2 = getattr(Person,"num") print(n2) #2.hasattr(obj,name) ;判断某个对象是否有指定的属性 print(hasattr(p,"name")) #3.setattr(obj,name,value):给某个对象的指定的属性赋值 setattr(p,"name","yangyang") print(getattr(p,"name")) #4.delattr(obj,name);删除某个对象的指定属性 delattr(p,"name") print(p.name)
2.练习
代码演示:
def news(): return "新闻" def music(): return "音乐" def video(): return "视频" def pe(): return "体育" def game(): return "游戏"
relectDemo.py
import test.testdemo op = input("请输入对应的跳转操作:") """ if op == "news": test.testdemo.news() elif op == "music": test.testdemo.music() elif op == "video": test.testdemo.video() elif op == "pe": test.testdemo.pe() else: test.testdemo.game() """ #通过反射解决上面的问题 res = hasattr(test.testdemo,op) if res: #有的话则进行获取 f = getattr(test.testdemo,op) print(f()) else: print("没有此功能")
三、Python2.x和Python3.x之间的区别
1.性能
3比2的效率低,但是3有更大的优化空间,效率正在追赶
2.编码
3默认使用的编码格式为utf-8,使得变量的命名范围更大【可以使用中文作为变量名】
3.语法
a.加入了with as关键字,还有True,False,None
b.除法运算使用的是/,整除使用的是//
c.加入了nonlocal关键字
d.去除print xxx ,加入 print(xxx)
e.去除raw_input语句 ,加入input()
4.字符串
2:8-bit存储
3:16-bit存储,只有一种类型str
5.数据类型
2:long【长整型】,int【整型】
3:int
3:增加了bytes类型,和字符串之间进行转换【encode,decode】
6.面向对象
更加完善【多继承】
7.异常
2:
try:
excpet Exception,e:
3:
try:
except Exception as e:
8.文件操作
2:打开文件需要两步:file(path),open(path)
3:打开文件只需要一步:open(path)