Чтение и запись делегатов CocoaAsyncSocket не являются стрельбой и организацией кода - PullRequest
4 голосов
/ 17 июня 2011

Я пытаюсь сделать следующее с измененной версией примера эхо-сервера, поставляемой с библиотекой cocoaasyncsocket:

1) открыть соединение со скриптом Python, выполняющим роль сервера
2) отправка данных // работает, но делегат не запускается
3) получить данные обратно // делегат не запускается
4) отключить // не отключить, видимо, все еще в моей теме

В настоящее время я открываю соединение в делегате didFinishLaunchingWithOptions, а затем пытаюсь отправить данные в делегат didConnectToHost. Затем я пытаюсь прочитать данные, возвращающиеся с клиента, а затем отключиться.

Я могу открыть соединение и отправить данные (которые сервер проверяет как полученные), но делегат didWriteDataWithTag никогда не срабатывает. Однако сервер получает данные. Затем сервер запускает некоторые данные, но didReadData также не запускается.

Помимо того, что делегаты чтения / записи не запускаются, похоже, я неправильно организовываю свой код, но я не уверен, как это выглядит в системе, управляемой событиями, в отличие от цикла выполнения (Я новичок в управляемых событиями вещах + сети). Если у меня есть ряд действий, соответствующие завершения которых инициированы их делегатами, должны ли делегаты делиться какими-то сообщениями - то есть мы получили сообщение "xxx", напишите "yyy"? Я бы предпочел иметь одну функцию, которая управляет всем этим. Есть ли канонический способ сделать это?

IPhoneConnectTestAppDelegate.m (фрагменты)

- (void)localConnect {
    NSError *error = nil;
    if (![asyncSocket connectToHost:@"localhost" onPort:5000 error:&error]) {
        DDLogError(@"Error connecting: %@", error);
    }
}

- (void)disconnect {
    [asyncSocket setDelegate:nil];
    [asyncSocket disconnect];
    [asyncSocket release];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Setup our socket (GCDAsyncSocket).
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:mainQueue];

    [self localConnect];

    // Add the view controller's view to the window and display.
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
}


- (void)onSocket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    NSString *output = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSLog(@"didReadData: %@", output);

}

- (void)onSocket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag {
    NSLog(@"didWriteDataWithTag");
}

- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
    NSLog(@"socket:%p didConnectToHost:%@ port:%hu", sock, host, port);
    if(port == 5000)
    {
        NSString *msg = @"q";
        NSData *dataOut = [msg dataUsingEncoding:NSASCIIStringEncoding];
        [asyncSocket writeData:dataOut withTimeout:-1 tag:0];
        [asyncSocket readDataWithTimeout:-1 tag:0];
        [self disconnect];
    }
}

tcpserver.py

# TCP server example
import socket, time
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(("", 5000))
server_socket.listen(5)

print "TCPServer Waiting for client on port 5000"

while 1:
    client_socket, address = server_socket.accept()
    print "I got a connection from ", address
    while 1:
        data = client_socket.recv(512)
        print "Data from client",data

        time.sleep(2)
        data = "xxx"
        print "Sending data to client",data
        client_socket.send (data)
        break;

Ответы [ 3 ]

6 голосов
/ 10 марта 2012

Я знаю, что это старый вопрос с уже принятым ответом, но для выяснения для людей, которые находят этот поток, ищущих что-то, причина, по которой методы делегата не были вызваны, заключается в том, что GCDAsynchSocket начинается с socket: вместо onsocket: то есть:

- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag

становится:

- (void) socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag
4 голосов
/ 22 июня 2011

Друг друга понял это для меня!Нам не удалось заставить GCDAsyncSocket работать должным образом (подключаться и писать, но не читать).Однако AsyncSocket функционирует во всех трех отношениях, и все делегаты работают правильно.

#import "AsyncSocket.h"
#import "tcp_clientViewController.h"

@implementation tcp_clientViewController

@synthesize socket;



-(IBAction)connect:(id)sender { 
    NSLog(@"(IBAction)connect");
    NSError *error = nil;
    if (![socket connectToHost:@"localhost" onPort:5000 error:&error]){
        NSLog(@"Error connecting: %@", error);
    }
}

-(IBAction)send:(id)sender {
    NSLog(@"(IBAction)send");


    char bytes[] = "abcd\r\n";
    NSData* data = [[NSData alloc] initWithBytes:bytes length:sizeof(bytes)];

    //NSString *msg = @"xxxxx\r\n";
    //NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];


    [socket writeData:data withTimeout:-1 tag:0];
    //NSData *data = [asyncSocket readDataWithTimeout:-1 tag:0];
    [data release];

    [socket readDataToData:[AsyncSocket LFData] withTimeout:-1 tag:0];
}

- (void)viewDidLoad {
    // initialize socket
    socket = [[AsyncSocket alloc] initWithDelegate:self];
}

#pragma mark AsyncSocket Delegate Methods
-(void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag {
    NSLog(@"socket:%p didWriteDataWithTag:%@", sock, tag);
}

- (void)socket:(AsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag {
    NSLog(@"socket:%p didWritePartialDataOfLength:%@ tag:%@", sock, partialLength, tag);
}

- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
    NSLog(@"socket:%p didConnectToHost:%@ port:%hu", sock, host, port);
}

- (void)socketDidSecure:(AsyncSocket *)sock
{
    NSLog(@"socket:%p socketDidSecure", sock);
}

- (void)socketDidDisconnect:(AsyncSocket *)sock withError:(NSError *)err
{
    NSLog(@"socket:%p socketDidDisconnect withError: %@", sock, err);
}

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSString* newStr = [NSString stringWithUTF8String:[data bytes]];    
    NSLog(@"socket socketDidReadData:%@", newStr);
}

-(IBAction)disconnect:(id)sender { }

#pragma mark View stuff
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)viewDidUnload {}

- (void)dealloc {
    self.socket = nil;
    [super dealloc];
}

@end
2 голосов
/ 17 июня 2011

Попробуйте использовать локальный носок для чтения команд и поместить их в команду записи

- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    [sock readDataToData:[AsyncSocket LFData] withTimeout:-1 tag:tag];
}
...