Tôi có chương trình dòng lệnh Cocoa, trong đó tôi cố gắng chạy chương trình NSTask
(tshark
để theo dõi mạng) và nhận dữ liệu từ đó trong thời gian thực. Vì vậy, tôi tạo NSFileHandle , gọi waitForDataInBackgroundAndNotify
để gửi thông báo và sau đó đăng ký lớp trợ giúp của tôi cho Trung tâm thông báo để xử lý dữ liệu, nhưng không một thông báo nào được gửi đến lớp trợ giúp của tôi.Lấy dữ liệu từ NSTask trong thời gian thực bằng cách sử dụng thông báo không hoạt động
Có ai có ý tưởng về điều gì có thể sai không?
Cảm ơn trước
Đây là mã của tôi:
#import <Foundation/Foundation.h>
#import <string>
#import <iostream>
@interface toff : NSObject {}
-(void) process:(NSNotification*)notification;
@end
@implementation toff
-(void) process:(NSNotification*)notification{
printf("Packet caught!\n");
}
@end
int main (int argc, const char * argv[]){
@autoreleasepool {
NSTask* tshark = [[NSTask alloc] init];
NSPipe* p = [NSPipe pipe];
NSFileHandle* read = [p fileHandleForReading];
toff* t1 = [[toff alloc] init];
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[read waitForDataInBackgroundAndNotify];
[nc addObserver:t1 selector:@selector(process:) name:nil object:nil];
printf("Type 'stop' to stop monitoring network traffic.\n");
[tshark setLaunchPath:@"/usr/local/bin/tshark"];
[tshark setStandardOutput:p];
[tshark launch];
while(1){
std::string buffer;
getline(std::cin, buffer);
if(buffer.empty()) continue;
else if(buffer.compare("stop") == 0){
[tshark interrupt];
break;
}
}
//NSData* dataRead = [read readDataToEndOfFile];
//NSLog(@"Data: %@", dataRead);
//NSString* stringRead = [[NSString alloc] initWithData:dataRead encoding:NSUTF8StringEncoding];
//NSLog(@"Output: %@", stringRead);
}
return 0;
}
EDIT: Khi tôi bỏ ghi chú nhận xét phần của mã và xóa tất cả những thứ thông báo, tất cả các dữ liệu mong muốn được chiết xuất từ tập tin xử lý sau hoàn thành nhiệm vụ. Tôi cũng tự hỏi, nếu vấn đề không thể là trên thực tế, chương trình của tôi là 'công cụ dòng lệnh' vì vậy tôi không chắc liệu nó có chạy vòng lặp hay không - như tài liệu Apple nói là cần thiết (trong waitForDataInBackgroundAndNotify thông điệp của NSFileHandle):
Bạn phải gọi phương thức này từ chuỗi có vòng chạy đang hoạt động.
Bạn thực sự nên thực hiện 'addObserver: selector: name: object:' thông điệp cụ thể hơn. Bạn hiện đang đăng ký thông báo * any *, không chỉ thông báo 'NSFileHandleReadCompletionNotification'. –
Vòng lặp chạy được tạo ra ngầm khi cần thiết, vì vậy bạn có thể giả định một cách an toàn “nó có [a] vòng lặp chạy”, nhưng bạn cần chạy nó. Một ứng dụng sẽ chạy vòng lặp chạy cho bạn, vì vậy tất cả những gì bạn cần làm là trả về, nhưng trong một công cụ dòng lệnh, bạn phải chạy vòng lặp chạy. Tôi khuyên bạn nên sử dụng NSFileHandle để đọc từ đầu vào tiêu chuẩn là tốt, và làm những gì tôi đã nói trong câu trả lời của tôi để chạy vòng lặp chạy cho đến khi nhiệm vụ thoát. –
@PeterHosey Ý tưởng hay - thanks.I đã cố gắng làm điều này nhưng không hiệu quả. Vì vậy, tôi bước trở lại đơn giản, bỏ qua dừng lại và đến với [this] (http://pastebin.com/qnhaUAjp) (Tôi cũng nhận thấy rằng dữ liệu được thông qua bởi 'NSFileHandle' là bằng cách nào đó đệm - không biết làm thế nào để thoát khỏi của nó) Sau khi bắt đầu, nó chờ đợi một lúc và sau đó viết 'Packet caught' một lần - sau đó không có gì. Nếu tôi uncomment 1 thì nó chờ đợi và sau đó viết 'Packet caught' không giới hạn thời gian.Và cuối cùng khi tôi cố gắng trích xuất dữ liệu và uncomment _2 -5_ nó chờ đợi một thời gian, viết dòng _2 & 3_ và sau đó freezes.No tai nạn, không có lỗi, chỉ cần không trích xuất dữ liệu. – user1023979