-
Notifications
You must be signed in to change notification settings - Fork 758
Expand file tree
/
Copy pathLVDebugConnection.m
More file actions
257 lines (220 loc) · 7.86 KB
/
LVDebugConnection.m
File metadata and controls
257 lines (220 loc) · 7.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
//
// LVDebuger.m
// CFSocketDemo
//
// Created by 罗何 on 9/16/15.
// Copyright © 2015年 luohe. All rights reserved.
//
#import "LVDebugConnection.h"
#import <CFNetwork/CFNetwork.h>
#import <TargetConditionals.h>
#import <sys/socket.h>
#import <netinet/in.h>
#import <arpa/inet.h>
#import <sys/ioctl.h>
#import <net/if.h>
#import <netdb.h>
#import "LVUtil.h"
#import "LView.h"
#define SOCKET_ERROR (-1)
#define SOCKET_CONNECTINTG (0)
#define SOCKET_SUCCESS (1)
// 调试器的默认IP和端口
static NSString* SERVER_IP = @"127.0.0.1";
static int SERVER_PORT = 9876;
@interface LVDebugConnection ()<NSStreamDelegate>
@property(nonatomic,strong) NSThread* myThread;
@property(nonatomic,assign) BOOL canWrite;
@property(nonatomic,assign) NSInteger state;
@property(atomic,strong) NSMutableArray* sendArray;
@end
@implementation LVDebugConnection{
NSOutputStream *_outputStream;
NSInputStream *_inputStream;
BOOL _outputStreamCompleted;
BOOL _inputStreamCompleted;
}
-(id) init{
self = [super init];
if( self ) {
static int index = 0;
self.myThread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:nil];
self.myThread.name = [NSString stringWithFormat:@"LV.Debuger.%d",index];
self.sendArray = [[NSMutableArray alloc] init];
self.receivedArray = [[NSMutableArray alloc] init];
[self startThread];
}
return self;
}
- (void) dealloc{
[self closeAll];
}
-(BOOL) isOk{
return self.state>0;
}
- (NSInteger) waitUntilConnectionEnd{
for(;self.state==SOCKET_CONNECTINTG;) {
[NSThread sleepForTimeInterval:0.01];
}
return self.state;
}
-(void) startThread{
[self.myThread start]; //启动线程
}
+(void) setDebugerIP:(NSString*) ip port:(int) port{
SERVER_IP = ip;
SERVER_PORT = port;
}
-(void) run:(id) obj{
@autoreleasepool {
[self Connect:SERVER_IP port:SERVER_PORT];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
[runLoop run];
}
}
- (NSString*) getCmd{
NSString* cmd = self.receivedArray.lastObject;
if( cmd ) {
[self.receivedArray removeLastObject];
}
return cmd;
}
- (void) sendCmd:(NSString*) cmdName info:(NSString*) info{
[self sendCmd:cmdName fileName:nil info:info];
}
- (void) sendCmd:(NSString*) cmdName fileName:(NSString*)fileName info:(NSString*) info{
NSMutableString* buffer = [[NSMutableString alloc] init];
if ( cmdName ) {
[buffer appendFormat:@"Cmd-Name:%@\n",cmdName];
}
if ( fileName ){
[buffer appendFormat:@"File-Name:%@\n",fileName];
}
[buffer appendString:@"\n"];
if ( info ){
[buffer appendFormat:@"%@",info];
}
[self sendString:buffer];
}
-(void)Connect:(NSString*) ip port:(NSUInteger)port{
#ifdef DEBUG
CFReadStreamRef readStream = NULL;
CFWriteStreamRef writeStream = NULL;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (__bridge CFStringRef)ip, (UInt32)port, &readStream, &writeStream);
// 记录已经分配的输入流和输出流
_inputStream = (__bridge NSInputStream *)readStream;
_outputStream = (__bridge NSOutputStream *)writeStream;
//设置属性SSL
// [_inputStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];
// [_outputStream setProperty:NSStreamSocketSecurityLevelSSLv3 forKey:NSStreamSocketSecurityLevelKey];
// CFWriteStreamSetProperty(writeStream, kCFStreamPropertySSLSettings, (__bridge CFTypeRef)([NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kCFBooleanFalse,kCFStreamSSLValidatesCertificateChain,kCFBooleanFalse,kCFStreamSSLIsServer,nil]));
// 设置代理,监听输入流和输出流中的变化
_inputStream.delegate = self;
_outputStream.delegate = self;
// Scoket是建立的长连接,需要将输入输出流添加到主运行循环
[_inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[_outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
// 打开输入流和输出流,准备开始文件读写操作
[_inputStream open];
[_outputStream open];
#endif
}
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode{
switch (eventCode) {
case NSStreamEventOpenCompleted:
if(aStream == _inputStream) _inputStreamCompleted = YES;
if(aStream == _outputStream) _outputStreamCompleted = YES;
if(_inputStreamCompleted && _outputStreamCompleted) self.state = SOCKET_SUCCESS;
break;
case NSStreamEventHasBytesAvailable:{
uint8_t buf[16 * 1024];
uint8_t *buffer = NULL;
NSUInteger len = 0;
if (![_inputStream getBuffer:&buffer length:&len]) {
NSInteger amount = [_inputStream read:buf maxLength:sizeof(buf)];
buffer = buf;
len = amount;
}
if (0 < len) {
//head
// NSUInteger d0 = buffer[0];
// NSUInteger d1 = buffer[1];
// NSUInteger d2 = buffer[2];
// NSUInteger d3 = buffer[3];
// len = (d0<<24) + (d1<<16) + (d2<<8) + d3;
// buffer = buffer + 4;
NSString *cmd = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding];
if ( cmd && cmd.length>0) {
LVLog(@"received CMD: %@", cmd);
[self.receivedArray insertObject:cmd atIndex:0];
}
// 关闭掉socket
if ( cmd.length<=0 ){
[self closeAll];
[self.receivedArray addObject:@"close"];
[self.receivedArray addObject:@"close"];
} else {
[self.lview callLuaToExecuteServerCmd];
}
}
}
break;
case NSStreamEventHasSpaceAvailable:
self.canWrite = YES;
break;
case NSStreamEventErrorOccurred:
case NSStreamEventEndEncountered:
[self closeAll];
[self.receivedArray addObject:@"close"];
[self.receivedArray addObject:@"close"];
[self.lview callLuaToExecuteServerCmd];
default:
break;
}
}
-(void) closeAll{
_outputStreamCompleted = NO;
_inputStreamCompleted = NO;
self.canWrite = FALSE;
self.state = -1;
[_inputStream close];
_inputStream = nil;
[_outputStream close];
_outputStream = nil;
if( !self.myThread.isCancelled ) {
[self.myThread cancel];
}
}
-(void) sendOneData{
NSData* data = self.sendArray.lastObject;
if( self.canWrite && data) {
[self.sendArray removeLastObject];
if( data.length > 0 ) {
NSInteger sendLength = [_outputStream write:data.bytes maxLength:data.length];
if( sendLength != data.length ) {
LVError(@"Debuger socket Send length Error : %d != %d", (int)sendLength, (int)data.length);
}
}
}
}
/////////////////////////发送信息给服务器////////////////////////
- (void) sendString:(NSString *)string
{
if( self.canWrite ) {
NSData* data = [string dataUsingEncoding:NSUTF8StringEncoding];
NSMutableData* buffer = [[NSMutableData alloc] init];
//head
// NSUInteger len = data.length;
// unsigned char head[4] = {0};
// head[0] = (len>>24);
// head[1] = (len>>16);
// head[2] = (len>>8);
// head[3] = (len);
// [buffer appendBytes:head length:4];
[buffer appendData:data];
[self.sendArray insertObject:buffer atIndex:0];
[self sendOneData];
}
}
@end