一, B/S 和 C/S 架构
C:client 客户端
S:server 服务器
B/S 架构: 使用浏览器进行通讯, 属于一种 C/S 架构
B:browser 浏览器
S:server 服务器
PC 端: bs 架构是未来的趋势, 统一了程序的入口
移动端: 微信公众号, 微信小程序, 统一了程序的入口
二, socket(套接字)
在开发中, socket 属于网络的最底层, 网络应用是基于 socket 开发
1 基于文件类型: 通过文件通信, 同一台机器, 用于并发开发
2 基于网络类型: 通过网络通信
两个程序的通信: 一个 server 文件, 一个 client 文件
三, 基于 tcp 协议的 socket 进行通信
要先启动服务器端, 再启动客户端
服务器端
步骤: 1 导入 socket 模块
2 创建 socket 的对象
3 给对象绑定 ip 和端口
4 开启服务, 处于监听状态
5 等待链接, 接收客户端的链接
6 接收客户端信息 / 发送信息给客户端
7 关闭客户端链接
8 关闭服务
- import socket
- sk = socket.socket() # 创建对象
- sk.bind(('127.0.0.1',8999)) # 绑定 ip 和端口到套接字
- sk.listen() # 开启服务, 监听链接
- conn,addr = sk.accept() # 接收客户端链接
- ret = conn.recv(1024) # 接收客户端的信息, 最多接收 1024 个字节, 返回的是 bytes 类型
- conn.send(b'hello') # 向客户端发送信息
- conn.close() # 关闭客户端的链接 (关闭客户端的套接字)
- sk.close() # 关闭服务 (关闭服务器套接字)
客户端:
1 创建对象
2 连接服务器
3 接收 / 发送信息
4 关闭链接, 关闭客户套接字
- # client.py 模块
- import socket
- sk = socket.socket() # 创建对象
- sk.connect(('127.0.0.1',8999)) # 连接服务器, 指定服务器的 IP 和端口
- sk.send(b'hello') # 给服务器端发送消息
- ret = sk.recv(1024) # 接收服务器端的消息
- sk.close() # 关闭链接 (关闭服务器套接字)
网盘应用:
- # 服务器端
- # server.py 模块
- import socket
- import os
- sk = socket.socket()
- sk.bind(('127.0.0.1',9000))
- sk.listen()
- conn,addr = sk.accept()
- filename = conn.recv(1024)
- with open(filename,'wb') as f:
- while 1:
- content = conn.recv(1048576)
- if not content:break
- f.write(content)
- print('Receive complete! file size:%s' % os.path.getsize(filename))
- conn.close()
- sk.close()
- # 客户端
- # client.py 模块
- import time
- import socket
- import os
- sk = socket.socket()
- sk.connect(('127.0.0.1',9000))
- path = r'D:\music\Refrain.mp3'
- sk.send('Refrain.mp3'.encode('utf-8'))
- size = os.path.getsize(path)
- print('file size:%s' % size )
- time.sleep(1)
- with open(path,'rb') as f:
- while size:
- concent = f.read(1024000)
- size -= len(concent)
- sk.send(concent)
- sk.close()
- print('Finish!')
服务器程序运行后, 强制停止程序, 下次启动程序是可能会报错 (因为没关闭套接字, 没关闭服务, 系统还没回收资源导致报错)
解决方案: 在 bink 前加上 sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
- # server.py 模块
- import socket
- sk = socket.socket() # 创建对象
- sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
- sk.bind(('127.0.0.1',8999)) # 绑定 ip 和端口到套接字
- sk.listen() # 开启服务, 监听链接
- conn,addr = sk.accept() # 接收客户端链接
- ret = conn.recv(1024) # 接收客户端的信息, 最多接收 1024 个字节, 返回的是 bytes 类型
- conn.send(b'hello') # 向客户端发送信息
- conn.close() # 关闭客户端的链接 (关闭客户端的套接字)
- sk.close() # 关闭服务 (关闭服务器套接字)
基于 tcp 协议的 socket 的弊端:
server 不能同时接收多个 client 端的链接, 只能一对一
四, 基于 udp 协议的 socket
基于 UDP 是无连接的, 服务器启动服务器后可以接收信息
- # server.py 模块
- import socket
- sk = socket.socket(type=socket.SOCK_DGRAM) # 创建对象, 创建套接字
- sk.bind(('127.0.0.1',9000)) # 绑定 IP 和端口
- msg,addr = sk.recvfrom(1024) # 接收客户端信息, 返回内容和客户端的 ip, 端口
- print(addr,msg.decode())
- sk.sendto(b'hello',addr) # 给客户端发送信息
- sk.close() # 关闭套接字
- # client.py 模块
- import socket
- sk = socket.socket(type=socket.SOCK_DGRAM) # 创建对象, 创建套接字
- ip = ('127.0.0.1',9000)
- sk.sendto('This is Client!'.encode('utf-8'),ip) # 给服务器发送信息 (信息, 服务器的 ip 和端口)
- msg,addr = sk.recvfrom(1024) # 接收服务器的信息, 返回信息和服务器的 ip 和端口
- print(addr,msg.decode())
- sk.close() # 关闭套接字
网络编程
来源: http://www.bubuko.com/infodetail-2766649.html