一,软件开发架构
C/S架构:client与server,客户端与服务器端架构,这种架构也是从用户层面(也可以是物理层面)来划分的,泛指客户端应用程序exe,程序需要先安装后,才能运行在用户的电脑上,对用户的电脑操作系统环境依赖较大
B/S架构:browser与server,浏览器端与服务器端架构,这种架构是从用户层面来划分的。
Browser浏览器,其实也是一种client客户端,只是这个客户端不需要大家去安装什么应用程序,只需在浏览器上通过http请求服务器端相关的资源(网页资源),客户端Browser浏览器就能进行增删改查
二,理解socket
socket是应用层与tcp/ip协议族通信的中间软件抽象层,它是一组接口,在设计模式中,socket其实就是一个门面模式,它把复杂的tcp/ip协议族隐藏在socket接口后面,对用户来说,一组简单的接口就是全部,让socket去组织数据,以符合指定的协议,站在python的角度上看,socket就是一个模块,我们通过调用模块中已经实现的方法,建立两个进程直接的连接和通信,也有人将socket说成ip+port,因为ip是用来标识互联网中的一台主机的位置,而port是用来标识这台机器上的一个应用程序。所以我们只有确立了ip和port就能找到一个应用程序,并且使用socket模块来与之通信
三,套接字(socket)初使用
启动一个使用Tcp协议的socket服务端与客户端
#语法结构 # server端 # import socket # k = socket.socket() 实例化一个对象 s # sk.bind(('ip地址',端口号)) # sk.listen(数字) #启动一个socket服务 # conn,addr = sk.accept() # 阻塞 ,完成三次握手,建立连接 # conn.send(bytes类型的内容) # msg = conn.recv(数字) #接收的最大字节数 # ...打印 操作 # conn.closs() # sk.close() #client端 #import socket #sk = socket.socket() #sk.connect(('服务器端的ip',服务器端的端口)) #sk.recv(数字) #接收的最大字节数 #sk.send() #sk.close() #完成四次握手,关闭连接
#server端 import socket sk = socket.socket() sk.bind(('127.0.0.1',9000)) sk.listen() while 1: try: conn,addr = sk.accept() while 1: msg = input('>>>') conn.send(msg.encode('utf-8')) msg = conn.recv(1024) print(msg.decode('utf-8')) conn.close() except UnicodeDecodeError: #异常处理:收到非utf8的字符串时,跳过 pass #client端 import socket sk = socket.socket() sk.connect(('127.0.0.1',9000)) while 1: msg = sk.recv(1024) print(msg.decode('utf-8')) re_msg = input('>>>') sk.send(re_msg.encode('utf-8'))
#server端 import socket sk = socket.socket() #由于被程序强制关闭,服务未完全关闭,端口未释放,导致端口占用报错,解决方案如下: sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #允许重用本地地址和端口 sk.bind(('127.0.0.1',9000)) sk.listen() while True: try: conn,addr = sk.accept() #对于tcp协议的socket server来说,不能同时接受多个client端的连接 while True: msg = input('>>>') conn.send(msg.encode('utf-8')) if msg == 'q':break msg = conn.recv(1024) if msg == b'q':break print(msg.decode('utf-8')) conn.close() except UnicodeDecodeError: pass #client端 import socket sk = socket.socket() sk.connect(('127.0.0.1',9000)) while True: msg = sk.recv(1024) if msg == b'q': break print(msg.decode('utf-8')) re_msg = input('>>>') sk.send(re_msg.encode('utf-8')) if re_msg == 'q': break sk.close()
#server端 import socket sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() conn,addr = sk.accept() filename = conn.recv(1024) print('-->filename:',filename) with open(filename,'wb') as f: content = conn.recv(4096) f.write(content) conn.close() sk.close() #client端 import time import socket sk = socket.socket() sk.connect(('127.0.0.1',8080)) sk.send('xx.py'.encode('utf-8')) time.sleep(0.1) with open(r'xx.py','rb') as f: content = f.read() print('len:',len(content)) sk.send(content) sk.close()
启动一个使用Udp协议的socket服务端与客户端
#语法结构 #server端 #import socket #udp_sk = socket.socket(type=socket.SOCK_DGRAM) #udp_sk.bind(('ip地址',端口号)) #msg(对方发的消息),addr(对方的地址)=udp_sk.recvfrom(接收的字节数) #udp_sk.sendto(b'要发给对方的消息',对方的地址) #udp_sk.close() #client端 #import socket #udp_sk = socket.socket(type=socket.SOCK_DGRAM) #sk.sendto('msg',(服务器端的地址)) #msg,addr = sk.recvfrom(接收的字节数)
#server端 import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.bind(('127.0.0.1',9000)) msg,addr = sk.recvfrom(1024) print(msg.decode('utf-8')) print(addr) sk.sendto('再见'.encode('utf-8'),addr) sk.close() #client端 import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.sendto('你好'.encode('utf-8'),('127.0.0.1',9000)) msg,addr = sk.recvfrom(1024) print(msg.decode('utf-8')) print('server addr:',addr) sk.close()
#server端 import socket sk = socket.socket(type=socket.SOCK_DGRAM) sk.bind(('127.0.0.1',9000)) while 1: msg,addr = sk.recvfrom(1024) print(addr,msg.decode('utf-8')) msg_send = input('>>>') sk.sendto(msg_send.encode('utf-8'),addr) #client端 import socket sk = socket.socket(type=socket.SOCK_DGRAM) while True: msg_send = input('>>>') sk.sendto(msg_send.encode('utf-8'),('127.0.0.1',9000)) msg,addr = sk.recvfrom(1024) print(msg.decode('utf-8')) print('server addr:',addr)