客户端:Client 浏览器:Browser 服务端:Server
B/S架构
优点 :丰富满足客户的个性化要求,安全性很容易保证,响应速度较快
缺点 : 需要开发客户端和服务器两套程序,开发成本维护成本较高,兼容性差,用户群固定
B/S架构
物理层
数据链路层
网络层
传输层
应用层(同时包含了会话层和表示层)
? Socket又称为套接字,它是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,通过这个接口就可以统一、方便的使用tcp/ip协议的功能
TCP : 可靠的, 面向连接的协议, 传输效率低, 全双工通信(发送缓存&接收缓存), 面向字节流
UDP : 不可靠, 无连接服务, 传输效率高, 无拥塞控制
socket服务端
import socket
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # tcp协议的serve
sk.bind((‘127.0.0.1‘,800)) # 调用操作系统资源,绑定一个ip和端口
sk.listen(5) # 监听
conn, addr = phone.accept() # 等客户端访问并建立连接
while True: # 循环收发消息
try:
res = conn.recv(1024) # 接收最大为1024字节
print(res.decode(‘utf-8‘))
ret = input(‘>>>‘).encode(‘utf-8‘)
conn.send(ret) # 直接发送消息, 不需要地址
except ConnectionResetError:
break
conn.close() # 关闭服务/连接
sk.close()
client客户端
import socket
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sk.connect((‘127.0.0.1‘,8080)) # 客户端/tcp协议的方法,和server端建立连接
while True: # 循环收发消息
res = input(‘>>>‘)
sk.send(res.encode(‘utf-8‘))
ret = sk.recv(1024)
print(ret.decode(‘utf-8‘))
sk.close() # 挂电话
粘包发生的本质 : tcp协议的传输是流式传输 数据与数据之间没有边界
发生情况:
解决办法
方法
import struct
# 将一个数字转换成长度的bytes类型。
ret = struct.pack(‘i‘,183346)
# 通过unpack反解回来
res = struct.unpack(‘i‘,ret)[0]
################## 服务端如下
import struct
import socket
sk = socket.socket()
sk.bind((‘127.0.0.1‘,9001))
sk.listen()
conn,addr = sk.accept()
msg1 = input(‘>>>‘).encode()
msg2 = input(‘>>>‘).encode()
# num = str() # ‘10001‘
# ret = num.zfill(4) # ‘0006‘
# conn.send(ret.encode(‘utf-8‘))
blen = struct.pack(‘i‘,len(msg1))
conn.send(blen)
conn.send(msg1)
conn.send(msg2)
conn.close()
sk.close()
# 生成一个随机字符串
import os
ret = os.urandom(32) # 生成一个由32个随机组成的字节
print(ret)
# 在进行加密传输,返回一个加密值与本地对照,可使用hashlib
#也可以使用hmac代替,更加简便
import hmac
a = hmc.new(加的字节, os.urandom32)
ret = h.digest() #加密的字节
print(ret)
socket服务端
import socket
sk = socket.socket(type=socket.SOCK_DGRAM) #创建一个服务器的套接字
sk.bind((‘127.0.0.1‘,9000)) #绑定服务器套接字
conn,addr = udp_sk.recvfrom(1024)
sk.sendto(b‘hi‘,addr) # 对话(接收与发送)
sk.close() # 关闭服务器套接字
socket客户端
import socket
ip_port=(‘127.0.0.1‘,9000)
udp_sk=socket.socket(type=socket.SOCK_DGRAM)
udp_sk.sendto(b‘hello‘,ip_port)
msg,addr=sk.recvfrom(1024)
print(msg.decode(‘utf-8‘),addr)
# 固定格式
import time
import socketserver # 引入模块
class Myserver(socketserver.BaseRequestHandler): # 类名自定义,但必须继承
def handle(self):
conn = self.request # 等同于conn管道
while True: # 编写传输内容
try:
content = conn.recv(1024).decode(‘utf-8‘)
conn.send(content.upper().encode(‘utf-8‘))
time.sleep(0.5)
except ConnectionResetError:
break
server = socketserver.ThreadingTCPServer((‘127.0.0.1‘,9001),Myserver)
server.serve_forever()
原文:https://www.cnblogs.com/tonxin66/p/13123724.html