Skip to content

Commit

Permalink
开源ios平台网络诊断组件
Browse files Browse the repository at this point in the history
  • Loading branch information
庞辉 committed Sep 15, 2015
0 parents commit 39bcb3d
Show file tree
Hide file tree
Showing 38 changed files with 4,566 additions and 0 deletions.
99 changes: 99 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
# 配置以什么语言format当前文件
# CPP: C, C++, Objective-C, ObjectiveC++;
Language: Cpp

#在llvm的配置基础上加定制配置
BasedOnStyle: llvm

# 访问修饰符如@public、@private、@protected的缩进
# 通常用在类定义和类别定义的私有变量进行修饰,作用表示很大,需要在变量前一个字符,设定为-1;
AccessModifierOffset: -2

# ??? 如果为true,将逃脱换行尽量远抛,否则将其搁在逃脱行的右侧, 没有什么用
AlignEscapedNewlinesLeft: false

# true: 表示对齐连续的紧跟注释(连续行使用双斜杠注释,包括在函数体内),多用于Model定义、property说明、私有成员变量说明;
AlignTrailingComments: true

#在紧跟注释之前所留空格数,一般建议为2个空格
SpacesBeforeTrailingComments: 2

#Block-Body的缩进列数
ObjCBlockIndentWidth: 4

#false:设置不允许一行的Block在一行显示;
AllowShortBlocksOnASingleLine: false


# true: 在超过规定列数之后,在方法声明中将所有参数换行显示(包括在方法声明和实现中,不包括C函数方法);
AllowAllParametersOfDeclarationOnNextLine: true

# true:允许较短(一般只有一行,多为内联C函数)的Function在一行显示,如“int f() { return 1; }”,规定设为false;
AllowShortFunctionsOnASingleLine: false

#true: 允许较短的if判断在一行显示,否则换行显示(没有自动加花括号);
AllowShortIfStatementsOnASingleLine: true

#??? true 允许较短的循环(while、for)在一行显示,否则换行显示(没有自动加花括号);
AllowShortLoopsOnASingleLine: true

#true:允许只有Break语句的case标签在一行显示,false:不允许(自动换行显示), 规范为不允许
AllowShortCaseLabelsOnASingleLine: false

#true:允许将较长的literal-String字符串分割成多行显示;
AlwaysBreakBeforeMultilineStrings: false

#设置代码的最大长度(回自动对代码长度进行换行显示,并对注释自动换行;当长度加大的时候,AllowAllParametersOfDeclarationOnNextLine=true失效)
ColumnLimit: 100

#连续行的缩进长度(通常缩进+设置值), 一般用于首参数小于后续参数的method名字、多行的String-literals
ContinuationIndentWidth: 4

#true: 将switch的case标签从switch表达式缩进一级;否则喝switch表达式对齐;
IndentCaseLabels: true

#缩进字符长度
IndentWidth: 4

#整个文件任意位置最大能够保持的连续空行数(如果超过MAX值,减少到Max行,小于不管;)
MaxEmptyLinesToKeep: 2

#true: 在@property之后添加一个空格,否则不添加空格
ObjCSpaceAfterProperty: true

#true: 在类与协议名的左括号之间添加一空格,否则不添加空格; 规范不添加;
ObjCSpaceBeforeProtocolList: true

#所有位置的指针星号(*)或取地址符号(&)对齐位置:Left、Middle、Right,当作为乘号时候居中 (规范为Right)
PointerAlignment: Right

#true:在赋值运算符之前添加一个空格,否则去掉;(规范为添加)
SpaceBeforeAssignmentOperators: true

#是否在括号之前添加一个空格,Never:任何情况都不添加;ControlStatements:只在控制结构(for、if、while)的地方添加空格;AlWays: 除开在function-like的的宏定义之外在任何地方都需要添加空格;(规范为ControlStatements)
SpaceBeforeParens: ControlStatements

#true:在空括号内添加空格,false:不添加;(规范不添加)
SpaceInEmptyParentheses: false

#true: 自动给mehtod-body内的括号和内容之间添加空格,false:不添加;(规范不添加)
SpacesInParentheses: false

#true: 在尖括号和内容之间各留一个空格,否则不添加;(规范为不添加)
SpacesInAngles: false

#true: 自动在Container literals(NSArray)之间添加空格
SpacesInContainerLiterals: true

#true: 在C风格的强制转换的时候添加空格;false: 不添加
SpacesInCStyleCastParentheses: false

#配置花括号的换行标准:Attach:任何时候都不换行;Allman:任何时候始终换行;Stroustrup: 只在function和else处换行;Linux:只在function、namespace、class的时候换行;GNU:始终换行,并在控制块添加一个额外的缩进,但在class、function、definitions的时候不换行;(规范)
BreakBeforeBraces: Linux


#当前配置生效开关,true:打开,false:关闭
DisableFormat: false
...

17 changes: 17 additions & 0 deletions LDNetDiagnoService.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Pod::Spec.new do |s|
s.name = 'LDNetDiagnoService'
s.version = '1.1.2'
s.license = {:type => 'MIT', :file => 'LICENSE'}
s.summary = '利用TCP Connect和traceroute的原理,对指定域名(通常为后台API的提供域名)进行网络诊断,并收集诊断日志。'
s.homepage = 'https://git.ms.netease.com/commonlibraryios/LDNetDiagnoService_IOS'
s.authors = { 'huipang' => '[email protected]' }
s.source = { :git => 'https://git.ms.netease.com/commonlibraryios/LDNetDiagnoService_IOS.git', :tag => "#{s.version}"}

s.platform = :ios
s.requires_arc = true
s.ios.deployment_target = '6.0'
s.ios.public_header_files = 'LDNetDiagnoService/LDNetDiagnoService.h'
s.ios.source_files = 'LDNetDiagnoService/*.{h,m}'
s.ios.framework = 'CoreTelephony'
s.ios.library = 'resolv'
end
41 changes: 41 additions & 0 deletions LDNetDiagnoService/LDNetConnect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// LDNetConnect.h
// LDNetDiagnoServiceDemo
//
// Created by ZhangHaiyang on 15-8-5.
// Copyright (c) 2015年 庞辉. All rights reserved.
//

#import <Foundation/Foundation.h>

/*
* @protocal LDNetConnectDelegate监测connect命令的的输出到日志变量;
*
*/
@protocol LDNetConnectDelegate <NSObject>
- (void)appendSocketLog:(NSString *)socketLog;
- (void)connectDidEnd:(BOOL)success;
@end


/*
* @class LDNetConnect ping监控
* 主要是通过建立socket连接的过程,监控目标主机是否连通
* 连续执行五次,因为每次的速度不一致,可以观察其平均速度来判断网络情况
*/
@interface LDNetConnect : NSObject {
}

@property (nonatomic, weak) id<LDNetConnectDelegate> delegate;

/**
* 通过hostaddress和port 进行connect诊断
*/
- (void)runWithHostAddress:(NSString *)hostAddress port:(int)port;

/**
* 停止connect
*/
- (void)stopConnect;

@end
160 changes: 160 additions & 0 deletions LDNetDiagnoService/LDNetConnect.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
//
// LDNetConnect.m
// LDNetDiagnoServiceDemo
//
// Created by ZhangHaiyang on 15-8-5.
// Copyright (c) 2015年 庞辉. All rights reserved.
//

#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <unistd.h>

#import "LDNetConnect.h"
#import "LDNetTimer.h"

#define MAXCOUNT_CONNECT 4

@interface LDNetConnect () {
BOOL _isExistSuccess; //监测是否有connect成功
int _connectCount; //当前执行次数

int tcpPort; //执行端口
NSString *_hostAddress; //目标域名的IP地址
NSString *_resultLog;
NSInteger _sumTime;
CFSocketRef _socket;
}

@property (nonatomic, assign) long _startTime; //每次执行的开始时间

@end

@implementation LDNetConnect
@synthesize _startTime;

/**
* 停止connect
*/
- (void)stopConnect
{
_connectCount = MAXCOUNT_CONNECT + 1;
}

/**
* 通过hostaddress和port 进行connect诊断
*/
- (void)runWithHostAddress:(NSString *)hostAddress port:(int)port
{
_hostAddress = hostAddress;
tcpPort = port;
_isExistSuccess = FALSE;
_connectCount = 0;
_sumTime = 0;
_resultLog = @"";
if (self.delegate && [self.delegate respondsToSelector:@selector(appendSocketLog:)]) {
[self.delegate
appendSocketLog:[NSString stringWithFormat:@"connect to host %@ ...", _hostAddress]];
}
_startTime = [LDNetTimer getMicroSeconds];
[self connect];
do {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (_connectCount < MAXCOUNT_CONNECT);
}

/**
* 建立socket对hostaddress进行连接
*/
- (void)connect
{
//创建套接字
CFSocketContext CTX = {0, (__bridge_retained void *)(self), NULL, NULL, NULL};
_socket = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_STREAM, IPPROTO_TCP,
kCFSocketConnectCallBack, TCPServerConnectCallBack, &CTX);

//设置地址
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(tcpPort);
addr.sin_addr.s_addr = inet_addr([_hostAddress UTF8String]);

CFDataRef address = CFDataCreate(kCFAllocatorDefault, (UInt8 *)&addr, sizeof(addr));

//执行连接
CFSocketConnectToAddress(_socket, address, 3);
CFRelease(address);
CFRunLoopRef cfrl = CFRunLoopGetCurrent(); // 获取当前运行循环
CFRunLoopSourceRef source =
CFSocketCreateRunLoopSource(kCFAllocatorDefault, _socket, _connectCount); //定义循环对象
CFRunLoopAddSource(cfrl, source, kCFRunLoopDefaultMode); //将循环对象加入当前循环中
CFRelease(source);
}

/**
* connect回调函数
*/
static void TCPServerConnectCallBack(CFSocketRef socket, CFSocketCallBackType type,
CFDataRef address, const void *data, void *info)
{
if (data != NULL) {
printf("connect");
LDNetConnect *con = (__bridge_transfer LDNetConnect *)info;
[con readStream:FALSE];
} else {

LDNetConnect *con = (__bridge_transfer LDNetConnect *)info;
[con readStream:TRUE];
}
}

/**
* 返回之后的一系列操作
*/
- (void)readStream:(BOOL)success
{
// NSString *errorLog = @"";
if (success) {
_isExistSuccess = TRUE;
NSInteger interval = [LDNetTimer computeDurationSince:_startTime] / 1000;
_sumTime += interval;
NSLog(@"connect success %ld", (long)interval);
_resultLog = [_resultLog
stringByAppendingString:[NSString stringWithFormat:@"%d's time=%ldms, ",
_connectCount + 1, (long)interval]];
} else {
_sumTime = 99999;
_resultLog =
[_resultLog stringByAppendingString:[NSString stringWithFormat:@"%d's time=TimeOut, ",
_connectCount + 1]];
}
if (_connectCount == MAXCOUNT_CONNECT - 1) {
if (_sumTime >= 99999) {
_resultLog = [_resultLog substringToIndex:[_resultLog length] - 1];
} else {
_resultLog = [_resultLog
stringByAppendingString:[NSString stringWithFormat:@"average=%ldms",
(long)(_sumTime / 4)]];
}
if (self.delegate && [self.delegate respondsToSelector:@selector(appendSocketLog:)]) {
[self.delegate appendSocketLog:_resultLog];
}
}

CFRelease(_socket);
_connectCount++;
if (_connectCount < MAXCOUNT_CONNECT) {
_startTime = [LDNetTimer getMicroSeconds];
[self connect];

} else {
if (self.delegate && [self.delegate respondsToSelector:@selector(connectDidEnd:)]) {
[self.delegate connectDidEnd:_isExistSuccess];
}
}
}

@end
Loading

0 comments on commit 39bcb3d

Please sign in to comment.