diff --git a/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Container/TJPConcreteSession.m b/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Container/TJPConcreteSession.m index 82901df..e310c2d 100644 --- a/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Container/TJPConcreteSession.m +++ b/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Container/TJPConcreteSession.m @@ -124,7 +124,7 @@ - (void)setupComponentWithConfig:(TJPNetworkConfig *)config { _seqManager = [[TJPSequenceManager alloc] init]; // 初始化协议解析器 - _parser = [[TJPMessageParser alloc] init]; + _parser = [[TJPMessageParser alloc] initWithRingBufferEnabled:YES]; // 初始化重连策略 _reconnectPolicy = [[TJPReconnectPolicy alloc] initWithMaxAttempst:config.maxRetry baseDelay:config.baseDelay qos:TJPNetworkQoSDefault delegate:self]; diff --git a/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/NetworkUtility/TJPNetworkDefine.h b/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/NetworkUtility/TJPNetworkDefine.h index e0dc484..19feedf 100644 --- a/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/NetworkUtility/TJPNetworkDefine.h +++ b/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/NetworkUtility/TJPNetworkDefine.h @@ -52,7 +52,7 @@ #define TJPMAX_BUFFER_SIZE (20 * 1024 * 1024) // 20MB 最大缓冲区大小 #define TJPMAX_TIME_WINDOW 60 // 60秒时间窗口,防重放攻击 -#define TJP_DEFAULT_RING_BUFFER_CAPACITY (1024 * 1024) // 缓冲区大小 初始64kb +#define TJP_DEFAULT_RING_BUFFER_CAPACITY (128 * 1024) // 缓冲区大小 初始128kb diff --git a/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Parser/TJPMessageParser.h b/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Parser/TJPMessageParser.h index 7ad44f2..b4b3a57 100644 --- a/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Parser/TJPMessageParser.h +++ b/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Parser/TJPMessageParser.h @@ -9,32 +9,84 @@ #import "TJPCoreTypes.h" NS_ASSUME_NONNULL_BEGIN +@class TJPParsedPacket, TJPMessageParser; + +@protocol TJPMessageStrategyDelegate +@optional +/// 是否使用环形缓冲区 YES使用 NO不使用 +- (BOOL)shouldUserRingBufferForParser:(TJPMessageParser *)parser; +/// 推荐缓冲区容量 +- (NSUInteger)recommendedCapacityForParser:(TJPMessageParser *)parser; +/// 缓冲区切换通知 +- (void)parser:(TJPMessageParser *)parser didSwitchToImplementation:(NSString *)impl reason:(NSString *)reason; +/// 缓冲区错误处理策略 YES继续使用当前实现 NO切换到备用实现 +- (BOOL)parser:(TJPMessageParser *)parser shouldContinueAfterError:(NSError *)error; + +@end + -@class TJPParsedPacket; @interface TJPMessageParser : NSObject -@property (nonatomic, assign, readonly) TJPParseState currentState; +@property (nonatomic, weak) id strategyDelegate; + + +/// 当前状态 +@property (nonatomic, assign, readonly) TJPParseState currentState; +/// 缓冲区 用于数据监控 @property (nonatomic, readonly) NSMutableData *buffer; +/// 当前协议头 +@property (nonatomic, readonly) TJPFinalAdavancedHeader currentHeader; +/// 当前策略 +@property (nonatomic, readonly) TJPBufferStrategy currentStrategy; /// 开关控制是否使用环形缓冲区 -@property (nonatomic, assign) BOOL useRingBuffer; +@property (nonatomic, readonly) BOOL isUseRingBuffer; +/// 缓冲区总容量 +@property (nonatomic, readonly) NSUInteger bufferCapacity; +/// 已使用大小 +@property (nonatomic, readonly) NSUInteger userdBufferSize; +/// 使用率 0.0 - 1.0 +@property (nonatomic, readonly) CGFloat bufferUsageRatio; /// 缓冲区添加数据 - (void)feedData:(NSData *)data; - /// 是否是完整数据 - (BOOL)hasCompletePacket; - /// 获取下一个数据 - (TJPParsedPacket *)nextPacket; - /// 重置数据 - (void)reset; + +- (instancetype)init; +/// 是否使用环形缓冲区初始化 - (instancetype)initWithRingBufferEnabled:(BOOL)enabled; +/// 使用缓冲区选择策略进行初始化 +- (instancetype)initWithBufferStrategy:(TJPBufferStrategy)strategy; +/// 完整配置初始化 +- (instancetype)initWithBufferStrategy:(TJPBufferStrategy)strategy capacity:(NSUInteger)capacity; + +//************************************************ +//新增控制切换 调试方法 + +/// 切换到环形缓冲区 +- (BOOL)switchToRingBuffer; +/// 切换到环形缓冲区并指定容量 +- (BOOL)switchToRingBufferWithCapacity:(NSUInteger)capacity; +/// 切换到传统缓冲区 +- (void)switchToTraditionBuffer; +/// 切换到最优模式 根据条件自动选择 +- (BOOL)switchToOptimalMode; + +/// 打印当前缓冲区信息 +- (void)printBufferStatus; +/// 获取缓冲区统计信息 +- (NSDictionary *)bufferStatistics; + + @end diff --git a/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Parser/TJPMessageParser.m b/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Parser/TJPMessageParser.m index e67eb3d..ed5ae5c 100644 --- a/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Parser/TJPMessageParser.m +++ b/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Parser/TJPMessageParser.m @@ -21,14 +21,21 @@ @interface TJPMessageParser () { TJPParseState _state; // 双缓冲区实现 - 通过开关控制 - NSMutableData *_buffer; // 旧实现:NSMutableData + NSMutableData *_traditionBuffer; // 旧实现:NSMutableData TJPRingBuffer *_ringBuffer; // 新实现:环形缓冲区 - BOOL _useRingBuffer; // 实现切换开关 + BOOL _isUseRingBuffer; // 实现切换开关 + TJPBufferStrategy _strategy; // 用户设置的策略 + NSUInteger _requestCapacity; // 用户请求的容量 // 安全相关 NSMutableSet *_recentSequences; //防重放攻击 NSDate *_lastCleanupTime; //定期清理计数器 + // 简单的错误统计 + NSUInteger _errorCount; + NSUInteger _totalOperations; + NSUInteger _switchCount; // 切换次数统计 + // 增加性能统计 CFTimeInterval _totalParseTime; // 总解析时间 @@ -41,34 +48,101 @@ @interface TJPMessageParser () { @implementation TJPMessageParser #pragma mark - Lifecycle - (instancetype)init { - return [self initWithRingBufferEnabled:NO]; + return [self initWithBufferStrategy:TJPBufferStrategyAuto]; } - (instancetype)initWithRingBufferEnabled:(BOOL)enabled { + TJPBufferStrategy strategy = enabled ? TJPBufferStrategyRingBuffer : TJPBufferStrategyTradition; + return [self initWithBufferStrategy:strategy]; +} + +- (instancetype)initWithBufferStrategy:(TJPBufferStrategy)strategy { + NSUInteger defaultCapacity = [self class].recommendedDefaultCapacity; + return [self initWithBufferStrategy:strategy capacity:defaultCapacity]; + +} + +- (instancetype)initWithBufferStrategy:(TJPBufferStrategy)strategy capacity:(NSUInteger)capacity { if (self = [super init]) { _state = TJPParseStateHeader; - _useRingBuffer = enabled; - - // 初始化缓冲区 - _buffer = [NSMutableData data]; - _ringBuffer = [[TJPRingBuffer alloc] initWithCapacity:TJP_DEFAULT_RING_BUFFER_CAPACITY]; + _strategy = strategy; + _requestCapacity = capacity; + _errorCount = 0; + _totalOperations = 0; + _switchCount = 0; // 安全相关初始化 _recentSequences = [NSMutableSet setWithCapacity:1000]; _lastCleanupTime = [NSDate date]; - + // 初始化缓冲区 + [self setupBuffersWithStrategy:strategy capacity:capacity]; + // 性能统计初始化 _totalParseTime = 0; _totalPacketCount = 0; _lastBenchmarkTime = CFAbsoluteTimeGetCurrent(); - TJPLOG_INFO(@"MessageParser 初始化完成,使用%@缓冲区", _useRingBuffer ? @"环形" : @"传统"); - + TJPLOG_INFO(@"MessageParser 初始化完成,使用%@缓冲区", _isUseRingBuffer ? @"环形" : @"传统"); } return self; } +- (void)setupBuffersWithStrategy:(TJPBufferStrategy)strategy capacity:(NSUInteger)capacity { + _traditionBuffer = [NSMutableData data]; + + switch (strategy) { + case TJPBufferStrategyTradition: + _isUseRingBuffer = NO; + _ringBuffer = nil; + break; + + case TJPBufferStrategyRingBuffer: + _isUseRingBuffer = [self setupRingBufferWithCapacity:capacity]; + break; + + case TJPBufferStrategyAuto: + default: + _isUseRingBuffer = [self autoSetupWithCapacity:capacity]; + break; + } +} + +- (BOOL)setupRingBufferWithCapacity:(NSUInteger)capacity { + // 检查容量合理性 + capacity = [self validateCapacity:capacity]; + + _ringBuffer = [[TJPRingBuffer alloc] initWithCapacity:capacity]; + if (!_ringBuffer) { + TJPLOG_ERROR(@"环形缓冲区初始化失败,容量: %luKB", (unsigned long)capacity / 1024); + [self recordError:@"环形缓冲区初始化失败"]; + return NO; + } + + return YES; + + + +} + +- (BOOL)autoSetupWithCapacity:(NSUInteger)capacity { + if (self.strategyDelegate && [self.strategyDelegate respondsToSelector:@selector(shouldUserRingBufferForParser:)]) { + BOOL shouldUse = [_strategyDelegate shouldUserRingBufferForParser:self]; + if (!shouldUse) { + TJPLOG_INFO(@"策略代理建议使用传统缓冲区"); + return NO; + } + } + + // 简单抉择逻辑 后续可以扩展为更完善逻辑 + if ([self shouldUseRingBufferByDefault]) { + return [self setupRingBufferWithCapacity:capacity]; + }else { + TJPLOG_INFO(@"自动选择传统缓冲区"); + return NO; + } +} + #pragma mark - Public Method - (void)feedData:(NSData *)data { @@ -77,17 +151,20 @@ - (void)feedData:(NSData *)data { if (!data || data.length == 0) { return; } + + _totalOperations++; // 防止缓冲区过大导致内存耗尽 - if (data.length > TJPMAX_BUFFER_SIZE || (_buffer.length + data.length) > TJPMAX_BUFFER_SIZE) { - TJPLOG_ERROR(@"数据大小超过限制: 当前缓冲区 %lu, 新增数据 %lu, 限制 %d", (unsigned long)_buffer.length, (unsigned long)data.length, TJPMAX_BUFFER_SIZE); + if (data.length > TJPMAX_BUFFER_SIZE ) { + TJPLOG_ERROR(@"数据大小超过限制: %lu > %d", (unsigned long)data.length, TJPMAX_BUFFER_SIZE); [self reset]; _state = TJPParseStateError; + [self recordError:@"数据大小超限"]; return; } // 根据开关选择实现 - if (_useRingBuffer) { + if (_isUseRingBuffer) { [self feedDataWithRingBuffer:data]; } else { [self feedDataWithLegacyBuffer:data]; @@ -105,7 +182,7 @@ - (BOOL)hasCompletePacket { return NO; } - if (_useRingBuffer) { + if (_isUseRingBuffer) { return [self hasCompletePacketWithRingBuffer]; } else { return [self hasCompletePacketWithLegacyBuffer]; @@ -120,8 +197,9 @@ - (TJPParsedPacket *)nextPacket { } CFTimeInterval startTime = CFAbsoluteTimeGetCurrent(); + TJPParsedPacket *result = nil; - if (_useRingBuffer) { + if (_isUseRingBuffer) { result = [self nextPacketWithRingBuffer]; } else { result = [self nextPacketWithLegacyBuffer]; @@ -136,27 +214,43 @@ - (TJPParsedPacket *)nextPacket { return result; } +- (void)reset { + [_traditionBuffer setLength:0]; + [_ringBuffer reset]; + _currentHeader = (TJPFinalAdavancedHeader){0}; + _state = TJPParseStateHeader; + + TJPLOG_INFO(@"MessageParser 重置完成"); +} + #pragma mark - Ring Buffer - (void)feedDataWithRingBuffer:(NSData *)data { - // 检查剩余空间 - if (_ringBuffer.availableSpace < data.length) { - TJPLOG_ERROR(@"环形缓冲区空间不足: 需要 %lu, 可用 %lu", - (unsigned long)data.length, (unsigned long)_ringBuffer.availableSpace); - [self reset]; - _state = TJPParseStateError; - return; - } - - NSUInteger written = [_ringBuffer writeData:data]; - if (written != data.length) { - TJPLOG_ERROR(@"环形缓冲区写入不完整: 期望 %lu, 实际 %lu", - (unsigned long)data.length, (unsigned long)written); - _state = TJPParseStateError; - return; + @try { + // 检查剩余空间 + if (_ringBuffer.availableSpace < data.length) { + TJPLOG_ERROR(@"环形缓冲区空间不足: 需要 %lu, 可用 %lu", + (unsigned long)data.length, (unsigned long)_ringBuffer.availableSpace); + [self reset]; + _state = TJPParseStateError; + return; + } + + NSUInteger written = [_ringBuffer writeData:data]; + if (written != data.length) { + TJPLOG_ERROR(@"环形缓冲区写入不完整: 期望 %lu, 实际 %lu", + (unsigned long)data.length, (unsigned long)written); + _state = TJPParseStateError; + return; + } + + } @catch (NSException *exception) { + TJPLOG_ERROR(@"环形缓冲区异常: %@", exception.reason); + [self handleRingBufferError:exception.reason]; + } -// TJPLOG_INFO(@"[环形Buffer] 收到数据: %lu 字节, 缓冲区使用率: %.1f%%", -// (unsigned long)data.length, _ringBuffer.usageRatio * 100); + // TJPLOG_INFO(@"[环形Buffer] 收到数据: %lu 字节, 缓冲区使用率: %.1f%%", + // (unsigned long)data.length, _ringBuffer.usageRatio * 100); } - (BOOL)hasCompletePacketWithRingBuffer { @@ -187,7 +281,7 @@ - (TJPParsedPacket *)nextPacketWithRingBuffer { - (BOOL)parseHeaderWithRingBuffer { if (![_ringBuffer hasAvailableData:sizeof(TJPFinalAdavancedHeader)]) { - TJPLOG_INFO(@"环形缓冲区数据不足,无法解析头部"); + TJPLOG_WARN(@"环形缓冲区数据不足,无法解析头部"); return NO; } @@ -260,18 +354,19 @@ - (TJPParsedPacket *)parseBodyWithRingBuffer { return packet; } -#pragma mark Legacy Buffer +#pragma mark Tradition Buffer - (void)feedDataWithLegacyBuffer:(NSData *)data { @synchronized (self) { - if ((_buffer.length + data.length) > TJPMAX_BUFFER_SIZE) { + if ((_traditionBuffer.length + data.length) > TJPMAX_BUFFER_SIZE) { TJPLOG_ERROR(@"传统缓冲区大小超过限制: 当前 %lu, 新增 %lu, 限制 %d", - (unsigned long)_buffer.length, (unsigned long)data.length, TJPMAX_BUFFER_SIZE); + (unsigned long)_traditionBuffer.length, (unsigned long)data.length, TJPMAX_BUFFER_SIZE); [self reset]; _state = TJPParseStateError; + [self recordError:@"缓冲区超限"]; return; } - [_buffer appendData:data]; + [_traditionBuffer appendData:data]; } // TJPLOG_INFO(@"[传统Buffer] 收到数据: %lu 字节", (unsigned long)data.length); @@ -279,10 +374,10 @@ - (void)feedDataWithLegacyBuffer:(NSData *)data { - (BOOL)hasCompletePacketWithLegacyBuffer { if (_state == TJPParseStateHeader) { - return _buffer.length >= sizeof(TJPFinalAdavancedHeader); + return _traditionBuffer.length >= sizeof(TJPFinalAdavancedHeader); } else if (_state == TJPParseStateBody) { uint32_t bodyLength = ntohl(_currentHeader.bodyLength); - return _buffer.length >= bodyLength; + return _traditionBuffer.length >= bodyLength; } return NO; } @@ -304,14 +399,14 @@ - (TJPParsedPacket *)nextPacketWithLegacyBuffer { } - (BOOL)parseHeaderWithLegacyBuffer { - if (_buffer.length < sizeof(TJPFinalAdavancedHeader)) { + if (_traditionBuffer.length < sizeof(TJPFinalAdavancedHeader)) { TJPLOG_INFO(@"数据长度不够数据头解析"); - return nil; + return NO; } TJPFinalAdavancedHeader currentHeader = {0}; // 解析头部 - [_buffer getBytes:¤tHeader length:sizeof(TJPFinalAdavancedHeader)]; + [_traditionBuffer getBytes:¤tHeader length:sizeof(TJPFinalAdavancedHeader)]; // 安全验证 NSError *validationError = nil; @@ -324,7 +419,7 @@ - (BOOL)parseHeaderWithLegacyBuffer { TJPLOG_INFO(@"解析数据头部成功...魔数校验成功!"); _currentHeader = currentHeader; // 移除已处理的Header数据 - [_buffer replaceBytesInRange:NSMakeRange(0, sizeof(TJPFinalAdavancedHeader)) withBytes:NULL length:0]; + [_traditionBuffer replaceBytesInRange:NSMakeRange(0, sizeof(TJPFinalAdavancedHeader)) withBytes:NULL length:0]; // TJPLOG_INFO(@"解析序列号:%u 的头部成功", ntohl(_currentHeader.sequence)); _state = TJPParseStateBody; @@ -334,13 +429,13 @@ - (BOOL)parseHeaderWithLegacyBuffer { - (TJPParsedPacket *)parseBodyWithLegacyBuffer { uint32_t bodyLength = ntohl(_currentHeader.bodyLength); - if (_buffer.length < bodyLength) { + if (_traditionBuffer.length < bodyLength) { TJPLOG_INFO(@"数据长度不够内容解析,等待更多数据..."); return nil; } - NSData *payload = [_buffer subdataWithRange:NSMakeRange(0, bodyLength)]; - [_buffer replaceBytesInRange:NSMakeRange(0, bodyLength) withBytes:NULL length:0]; + NSData *payload = [_traditionBuffer subdataWithRange:NSMakeRange(0, bodyLength)]; + [_traditionBuffer replaceBytesInRange:NSMakeRange(0, bodyLength) withBytes:NULL length:0]; // 验证CRC32校验和 if (![self validateChecksum:_currentHeader.checksum forData:payload]) { @@ -374,14 +469,6 @@ - (BOOL)validateChecksum:(uint32_t)expectedChecksum forData:(NSData *)data { return YES; } -- (void)reset { - [_buffer setLength:0]; - [_ringBuffer reset]; - _currentHeader = (TJPFinalAdavancedHeader){0}; - _state = TJPParseStateHeader; - - TJPLOG_INFO(@"MessageParser 重置完成"); -} #pragma mark - Private Method - (BOOL)validateHeader:(TJPFinalAdavancedHeader)header error:(NSError **)error { @@ -528,16 +615,310 @@ - (void)cleanupExpiredSequences { } +- (BOOL)shouldUseRingBufferByDefault { + // 内存检查 + NSUInteger totalMemoryMB = [NSProcessInfo processInfo].physicalMemory / (1024 * 1024); + + if (totalMemoryMB < 1024) { + TJPLOG_INFO(@"设备内存较少(%luMB),选择传统缓冲区", (unsigned long)totalMemoryMB); + return NO; + } + + // 历史错误率检查(简单版本) + if (_totalOperations > 100 && (CGFloat)_errorCount / _totalOperations > 0.1) { + TJPLOG_INFO(@"历史错误率较高(%.1f%%),选择传统缓冲区", + (CGFloat)_errorCount / _totalOperations * 100); + return NO; + } + + // 默认倾向于使用环形缓冲区 + return YES; + +} + + +- (NSUInteger)validateCapacity:(NSUInteger)capacity { + if (self.strategyDelegate && [self.strategyDelegate respondsToSelector:@selector(recommendedCapacityForParser:)]) { + NSUInteger delegateCapacity = [self.strategyDelegate recommendedCapacityForParser:self]; + if (delegateCapacity > 0) { + capacity = delegateCapacity; + } + } + + // 边界检查 + NSUInteger minCapacity = 16 * 1024; //最小16KB + NSUInteger maxCapacity = 1024 * 1024; //最大1MB + + if (capacity < minCapacity) { + TJPLOG_WARN(@"容量过小(%luKB),调整为最小值%luKB", + (unsigned long)capacity / 1024, (unsigned long)minCapacity / 1024); + capacity = minCapacity; + } else if (capacity > maxCapacity) { + TJPLOG_WARN(@"容量过大(%luKB),调整为最大值%luKB", + (unsigned long)capacity / 1024, (unsigned long)maxCapacity / 1024); + capacity = maxCapacity; + } + + return capacity; + +} + + ++ (NSUInteger)recommendedDefaultCapacity { + NSUInteger totalMemoryMB = [NSProcessInfo processInfo].physicalMemory / (1024 * 1024); + + if (totalMemoryMB < 1024) { + return 16 * 1024; // 16KB - 低端设备 + } else if (totalMemoryMB < 2048) { + return 32 * 1024; // 32KB - 中端设备 + } else if (totalMemoryMB < 4096) { + return 64 * 1024; // 64KB - 高端设备 + } else { + return 128 * 1024; // 128KB - 顶级设备 + } +} + + +- (NSString *)strategyDescription:(TJPBufferStrategy)strategy { + switch (strategy) { + case TJPBufferStrategyAuto: return @"自动选择"; + case TJPBufferStrategyTradition: return @"强制传统"; + case TJPBufferStrategyRingBuffer: return @"强制环形"; + default: return @"未知策略"; + } +} + +- (NSString *)stateDescription:(TJPParseState)state { + switch (state) { + case TJPParseStateHeader: return @"等待头部"; + case TJPParseStateBody: return @"等待消息体"; + case TJPParseStateError: return @"错误状态"; + default: return @"未知状态"; + } +} + +#pragma mark - Method Change +- (BOOL)switchToRingBuffer { + return [self switchToRingBufferWithCapacity:_requestCapacity]; +} + +- (BOOL)switchToRingBufferWithCapacity:(NSUInteger)capacity { + if (_isUseRingBuffer) { + TJPLOG_INFO(@"已经在使用环形缓冲区"); + return YES; + } + + // 创建新的环形缓冲区 + capacity = [self validateCapacity:capacity]; + TJPRingBuffer *newRingBuffer = [[TJPRingBuffer alloc] initWithCapacity:capacity]; + + if (!newRingBuffer) { + TJPLOG_ERROR(@"环形缓冲区创建失败"); + [self recordError:@"环形缓冲区创建失败"]; + return NO; + } + + // 数据迁移 + if (_traditionBuffer.length > 0) { + NSUInteger written = [newRingBuffer writeData:_traditionBuffer]; + if (written != _traditionBuffer.length) { + TJPLOG_WARN(@"数据迁移不完整: %lu/%lu", + (unsigned long)written, (unsigned long)_traditionBuffer.length); + } + TJPLOG_INFO(@"成功迁移 %lu 字节数据到环形缓冲区", (unsigned long)written); + } + + // 切换实现 + _ringBuffer = newRingBuffer; + [_traditionBuffer setLength:0]; + _isUseRingBuffer = YES; + _switchCount++; + + TJPLOG_INFO(@"成功切换到环形缓冲区,容量: %luKB", (unsigned long)capacity / 1024); + + // 通知代理 + [self notifyStrategySwitch:@"环形缓冲区" reason:@"手动切换"]; + + return YES; +} + +- (void)switchToTraditionBuffer { + if (!_isUseRingBuffer) { + TJPLOG_INFO(@"已经在使用传统缓冲区"); + return; + } + + // 数据迁移 + if (_ringBuffer.usedSize > 0) { + NSData *data = [_ringBuffer readData:_ringBuffer.usedSize]; + if (data) { + [_traditionBuffer appendData:data]; + TJPLOG_INFO(@"成功迁移 %lu 字节数据到传统缓冲区", (unsigned long)data.length); + } + } + + // 切换实现 + _isUseRingBuffer = NO; + _switchCount++; + + TJPLOG_INFO(@"成功切换到传统缓冲区"); + + // 通知代理 + [self notifyStrategySwitch:@"传统缓冲区" reason:@"手动切换"]; +} + +- (BOOL)switchToOptimalMode { + BOOL shouldUseRing = [self shouldUseRingBufferByDefault]; + + if (shouldUseRing && !_isUseRingBuffer) { + return [self switchToRingBuffer]; + } else if (!shouldUseRing && _isUseRingBuffer) { + [self switchToTraditionBuffer]; + return YES; + } + + TJPLOG_INFO(@"当前模式已是最优模式"); + return YES; +} + +- (void)handleRingBufferError:(NSString *)reason { + [self recordError:reason]; + + // 咨询策略代理 + if ([_strategyDelegate respondsToSelector:@selector(parser:shouldContinueAfterError:)]) { + NSError *error = [NSError errorWithDomain:@"TJPRingBufferError" + code:-1 + userInfo:@{NSLocalizedDescriptionKey: reason}]; + BOOL shouldContinue = [_strategyDelegate parser:self shouldContinueAfterError:error]; + if (!shouldContinue) { + TJPLOG_WARN(@"策略代理建议切换实现,原因: %@", reason); + [self switchToTraditionBuffer]; + return; + } + } + + // 简单的错误处理策略 + if (_errorCount > 5 && _totalOperations > 10) { + CGFloat errorRate = (CGFloat)_errorCount / _totalOperations; + if (errorRate > 0.3) { // 错误率超过30% + TJPLOG_WARN(@"环形缓冲区错误率过高(%.1f%%),切换到传统模式", errorRate * 100); + [self switchToTraditionBuffer]; + return; + } + } + + // 继续使用环形缓冲区,但重置状态 + [self reset]; + _state = TJPParseStateError; +} + +- (void)recordError:(NSString *)reason { + _errorCount++; + TJPLOG_ERROR(@"记录错误: %@ (总错误: %lu, 总操作: %lu)", + reason, (unsigned long)_errorCount, (unsigned long)_totalOperations); +} + +- (void)notifyStrategySwitch:(NSString *)implementation reason:(NSString *)reason { + if ([_strategyDelegate respondsToSelector:@selector(parser:didSwitchToImplementation:reason:)]) { + [_strategyDelegate parser:self didSwitchToImplementation:implementation reason:reason]; + } +} + + +#pragma mark - 属性实现 +- (BOOL)isUsingRingBuffer { + return _isUseRingBuffer; +} + +- (NSUInteger)bufferCapacity { + if (_isUseRingBuffer) { + return _ringBuffer.capacity; + } else { + return TJPMAX_BUFFER_SIZE; // 传统缓冲区的理论最大容量 + } +} + +- (NSUInteger)usedBufferSize { + if (_isUseRingBuffer) { + return _ringBuffer.usedSize; + } else { + return _traditionBuffer.length; + } +} + +- (CGFloat)bufferUsageRatio { + if (_isUseRingBuffer) { + return _ringBuffer.usageRatio; + } else { + return (CGFloat)_traditionBuffer.length / TJPMAX_BUFFER_SIZE; + } +} + +- (TJPBufferStrategy)currentStrategy { + return _strategy; +} + +- (TJPParseState)currentState { + return _state; +} -#pragma mark - 单元测试 - (NSMutableData *)buffer { - return _buffer; + if (_isUseRingBuffer) { + NSUInteger usedSize = _ringBuffer.usedSize; + if (usedSize > 0) { + NSMutableData *testBuffer = [NSMutableData dataWithCapacity:usedSize]; + char *tempBuffer = malloc(usedSize); + if (tempBuffer) { + NSUInteger peeked = [_ringBuffer peekBytes:tempBuffer length:usedSize]; + if (peeked == usedSize) { + [testBuffer appendBytes:tempBuffer length:usedSize]; + } + free(tempBuffer); + } + return testBuffer; + } + return [NSMutableData data]; + } else { + return _traditionBuffer; + } } - (TJPFinalAdavancedHeader)currentHeader { return _currentHeader; } + +#pragma mark - 监控和调试方法 + +- (void)printBufferStatus { + TJPLOG_INFO(@"=== MessageParser 缓冲区状态 ==="); + TJPLOG_INFO(@"当前策略: %@", [self strategyDescription:_strategy]); + TJPLOG_INFO(@"当前实现: %@", _isUseRingBuffer ? @"环形缓冲区" : @"传统缓冲区"); + TJPLOG_INFO(@"缓冲区容量: %luKB", (unsigned long)self.bufferCapacity / 1024); + TJPLOG_INFO(@"已使用大小: %luKB", (unsigned long)self.usedBufferSize / 1024); + TJPLOG_INFO(@"使用率: %.1f%%", self.bufferUsageRatio * 100); + TJPLOG_INFO(@"解析状态: %@", [self stateDescription:_state]); + TJPLOG_INFO(@"错误统计: %lu/%lu (%.2f%%)", + (unsigned long)_errorCount, (unsigned long)_totalOperations, + _totalOperations > 0 ? (CGFloat)_errorCount / _totalOperations * 100 : 0); + TJPLOG_INFO(@"切换次数: %lu", (unsigned long)_switchCount); +} + +- (NSDictionary *)bufferStatistics { + return @{ + @"strategy": [self strategyDescription:_strategy], + @"implementation": _isUseRingBuffer ? @"ring_buffer" : @"legacy", + @"capacity": @(self.bufferCapacity), + @"usedSize": @(self.usedBufferSize), + @"usageRatio": @(self.bufferUsageRatio), + @"state": [self stateDescription:_state], + @"errorCount": @(_errorCount), + @"totalOperations": @(_totalOperations), + @"errorRate": @(_totalOperations > 0 ? (CGFloat)_errorCount / _totalOperations : 0), + @"switchCount": @(_switchCount) + }; +} + @end diff --git a/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Utility/TJPCoreTypes.h b/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Utility/TJPCoreTypes.h index 6cba318..cbd22cf 100644 --- a/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Utility/TJPCoreTypes.h +++ b/iOS-Network-Stack-Dive/CoreNetworkStack/TJPIMCore/Utility/TJPCoreTypes.h @@ -110,6 +110,12 @@ typedef NS_ENUM(NSUInteger, TJPParseState) { TJPParseStateError = 1 << 2 // 解析出错 }; +typedef NS_ENUM(NSUInteger, TJPBufferStrategy) { + TJPBufferStrategyAuto = 0, //默认自动选择 + TJPBufferStrategyTradition, //传统NSMutableData缓冲区 + TJPBufferStrategyRingBuffer //环形缓冲区 +}; + typedef NS_ENUM(NSUInteger, TJPNetworkQoS) { TJPNetworkQoSDefault = 1 << 0, TJPNetworkQoSBackground = 1 << 1,