Python中提供了两个级别访问的网络服务:
1、低级别的网络服务Socket
2、高级别的网络服务模块SocketServer
Socket和SocketServer区别:
整个计算机网络是由协议构成,如Web中的http协议、传输协议TCP和UDP等等,通信需要socket来实现。socket直接和传输层后下面的底层网络协议打交道(socket本身让我们直接与TCP打交道),底层socket已经建立好则可以互相通信。互联网现在主流的网络层协议是IPv4,IPv6是下一代网络层协议但不主流,IPv6解决的是IPv4地址耗尽的问题,其实为了应对IPv4资源少的问题产生了局域网和网关。
SocketServer简化了编写网络服务程序的任务,同时SocketServer模块也是Python标准库中很多服务器框架的基础,总的来时,SocketServer是一个种更集成的开发网络开发框架,开发人员可以专注于事务的细节,而不是使用Socket的各种细节。不过学习还是得一步一步来。
网络原理:
网络原理是掌握socket原理的必经之路,首先来介绍一下网络的七层基本框架,包含应用层、会话层、表示层、传输层、网络层、链路层和物理层(当前把网络七层模型中的会话、表示、应用层统称为应用层。)
应用层 文件传输、文件服务、电子邮件 http ftp smtp dns
传输层 通过端对端的接口 TCP UDP
网络层 为数据包选择路由 IP ICMP
数据链路层 传输有地址的帧、错误检测功能 ARP
物理层 物理媒体
socket中可以通过建立网络连接来实现计算机的交互
一个简易的交互实例:1、客户端 2、服务器端
在此之前,大家应该先了解一下计算机网络中的三次握手和四次断开原理,这个原理保证了连接的正常进行。
客户端分为:1、申明网络协议;2、请求建立连接;3、发送数据;4、接收数据;5、关闭连接
服务器端分为:1、申明协议实例监听者;2、绑定监听IP和端口;3、启动监听者监听;4、建立连接;5、接收和发送数据;6、断开连接
客户端步骤:
client = socket.socket()#创建一个客户端实例
在客户端连接时要注意,connect中只能接收一个参数,所以我们应该传入一个ID和具体端口来确定一个具体的连接
client.connect(('**',***))#客户端连接
client.send(cmd.encode("utf-8"))#发送请求
cmd_res_size = client.recv(1024) ##接受命令结果的长度
client.close()#断开连接
服务器步骤:
#创建实例 server = socket.socket()
和客户端一样,connect中只能接收一个参数,应该传入一个ID和具体端口来确定一个具体的连接
#绑定和监听 server.bind(('**',***) ) server.listen()
#接收一个客户端 conn, addr = server.accept()
#接收指令 data = conn.recv(1024)
#发送文件 conn.send(cmd_res.encode("utf-8"))
server.close()#关闭连接
实例代码:
以上只是一个步骤,但是实际过程中,会遇到很多问题,比如如何循环交互?如何面对对个客户端请求得问题?
#服务器端 import socket #声明类型 server = socket.socket() #绑定要监听哪个端口 server.bind(('localhost',999)) #监听(开始监听) server.listen(5) print('开始等电话') #等待客户端的请求(等电话打进来) while True: conn,addr = server.accept() print('电话来了') count = 0 while conn: # 接收大小 data = conn.recv(1024) print('recv:',data) #返回客户端的值 try: if not data: print('no message!') except: break conn.send(data.upper()) count+=1 if count>10:break server.close()
#客户端 #只能发送byte类型 import socket client = socket.socket()#定义协议类型同时生成socket链接对象 #链接 client.connect((('localhost',999)))#传入一个元组(IP,端口) #发送 # client.send(b'Hello world') # client.send('哈哈哈哈哈'.encode('utf-8')) #用户循环输入 while True: msg = input('>>:').strip() if len(msg) == 0:continue client.send(msg.encode('utf-8')) data = client.recv(1024) print('recv:',data.decode()) #接收服务器的返回,必须声明接收的字节大小 # data = client.recv(1024) client.close()