网络编程
一、B/S和C/S架构
C/S架构:使用客户端(程序)来与服务器进行通讯
C:client 客户端
S:server 服务器
B/S架构:使用浏览器进行通讯,属于一种C/S架构
B:browser 浏览器
S:server 服务器
PC端:bs架构是未来的趋势,统一了程序的入口
移动端:微信公众号、微信小程序,统一了程序的入口
二、socket(套接字)
在开发中,socket属于网络的最底层,网络应用是基于socket开发
① 基于文件类型:通过文件通信,同一台机器,用于并发开发
② 基于网络类型:通过网络通信
两个程序的通信:一个server文件,一个client文件
三、基于tcp协议的socket进行通信
要先启动服务器端,再启动客户端
服务器端
步骤:① 导入socket模块
② 创建socket的对象
③ 给对象绑定ip和端口
④ 开启服务,处于监听状态
⑤ 等待链接,接收客户端的链接
⑥ 接收客户端信息/发送信息给客户端
⑦ 关闭客户端链接
⑧ 关闭服务
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() # 关闭服务(关闭服务器套接字)
客户端:
① 创建对象
② 连接服务器
③ 接收/发送信息
④ 关闭链接,关闭客户套接字
# 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() # 关闭套接字