【发布时间】:2013-03-10 18:27:59
【问题描述】:
我在自己开发的 iOS 应用上完美运行了出色的 GCDAsyncSocket。
我只是在设置一个 Mac OSX 命令行程序,该程序以类似的方式使用该库来登录到 SQLite DB,但无法让它甚至尝试连接到主机。不会产生错误。该程序不会崩溃或任何事情,所以不知道它为什么不工作。有谁知道为什么这不起作用?
控制台仅打印出以下内容(没有连接/断开/读取/写入日志,即未调用套接字委托方法):
Attempting to connect to host: 192.168.1.2 on port: 1234 to refresh
这是我正在使用的大量代码:
main.m
#import <Foundation/Foundation.h>
#import "LoggerClass.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
LoggerClass *logger = [[LoggerClass alloc] init];
[logger startLogging];
while (logger.status == 0) {
sleep(1);
continue;
}
return 0;
}
}
LoggerClass.h
#import <Foundation/Foundation.h>
#import "Device.h"
@interface LoggerClass : NSObject <DeviceProtocol>
@property (nonatomic, strong) FMDatabase *database;
@property (nonatomic, strong) NSArray *devices;
@property (nonatomic) int status;
- (void)startLogging;
@end
LoggerClass.m
#import "LoggerClass.h"
#import "FMDatabase.h"
#define kLoggingInProgress 0
#define kLoggingCompleted 1
@implementation LoggerClass
@synthesize database = _database;
@synthesize devices = _devices;
@synthesize status = _status;
- (id)init {
if (self = [super init]) {
self.status = kLoggingInProgress;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:@"database.sqlite"];
self.database = [FMDatabase databaseWithPath:path];
Device *d1 = [Device deviceWithName:@"Device 1" address:@"192.168.1.2" delegate:self];
self.devices = [NSArray arrayWithObjects:d1, nil];
}
return self;
}
- (void)startLogging {
for (Device *d in self.devices) {
[d refresh];
}
}
- (void)didUpdateDevice:(Device *)device {
// Insert DB entry code
NSLog(@"%@ has finished Logging", device.name);
self.status = kLoggingCompleted; // This would obviously register completed if only 1 device returned but for sake of this test that fine
}
@end
Device.h
#import <Foundation/Foundation.h>
#import "GCDAsyncSocket.h"
@protocol DeviceProtocol;
@interface Device : NSObject
@property (nonatomic, weak) id<DeviceProtocol> delegate;
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *address;
@property (nonatomic, strong) GCDAsyncSocket *socket;
+ (Device *)deviceWithName:(NSString *)n address:(NSString *)a delegate:(id<DeviceProtocol>)d;
- (void)refresh;
@end
@protocol DeviceProtocol <NSObject>
@required
- (void)didUpdateDevice:(Device *)device;
@end
Device.m
#import "Device.h"
#define DEVICE_PORT 1234
@implementation Device
@synthesize delegate = _delegate;
@synthesize name = _name;
@synthesize address = _address;
@synthesize socket = _socket;
- (id)initWithName:(NSString *)name andAddress:(NSString *)address andDelegate:(id<DeviceProtocol>)delegate { // Designated Initialiser
if (self = [super init]) {
self.socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
self.name = name;
self.address = address;
self.delegate = delegate;
}
return self;
}
+ (Device *)deviceWithName:(NSString *)n address:(NSString *)a delegate:(id<DeviceProtocol>)d {
return [[Device alloc] initWithName:n andAddress:a andDelegate:d];
}
#pragma mark - GCD Async Socket Delegate Methods
- (void)socket:(GCDAsyncSocket *)sender didConnectToHost:(NSString *)host port:(UInt16)port {
NSLog(@"Connected to: %@", self.address);
}
- (void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)error {
NSLog(@"Socket for %@ disconnected %@.", self.address, error);
if (self.delegate) [self.delegate didUpdateDevice:self];
}
- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
NSLog(@"socket:didWriteDataWithTag:");
}
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
NSLog(@"socket:didReadData:withTag:");
[self.socket disconnect];
}
- (void)refresh {
if ([self.address length] == 0) { [self.delegate didUpdateDevice:self]; return; }
NSLog(@"Attempting to connect to host: %@ on port: %i to refresh", self.address, DEVICE_PORT);
NSError *error = nil;
if (![self.socket connectToHost:self.address onPort:DEVICE_PORT withTimeout:15 error:&error]) NSLog(@"ERROR: %@", error);
NSData *dataToSend;
// Build byte data here to send to device (exact same data works on iOS)
[self.socket writeData:dataToSend withTimeout:10 tag:0];
[self.socket readDataWithTimeout:-1 tag:0];
}
@end
【问题讨论】:
-
你有一个很好的问题。但是,我删除了您问题的 Linux 部分,这确实是一个完全不同的问题。你会做一些单独的搜索并发布关于在 Linux 上使用 Objective-C、FMDB 和 GCDAsyncSocket 的新问题吗?
-
谢谢诺亚。采取的观点 - 希望快速将 Linux 问题附加到这个问题上,是/否 GCDAsyncSocket 是否在 Linux 上工作!关于我的问题的注释:关于此问题的其他 2 个类似问题似乎表明 ARC 已删除该对象(在这种情况下将转换为对象 Device *d1),因此没有委托消息。但是,当我在 main.m while 循环中对 @continue 进行断点时,LoggerClass *logger obj 仍然与 d1 一起存在,因此它没有超出范围。谢谢。
-
Mac 防火墙有可能阻止这个吗?您是否尝试过在 localhost 上运行的服务器?另外,您是否尝试过已知工作的主机和端口,例如 HTTP 或 SMTP 服务器?
-
Erps,没关系。见下文。
标签: objective-c macos cocoaasyncsocket gcdasyncsocket