首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSFileHandle函数acceptConnectionInBackgroundAndNotify在第二次调用时不起作用

NSFileHandle函数acceptConnectionInBackgroundAndNotify在第二次调用时不起作用
EN

Stack Overflow用户
提问于 2011-01-13 15:26:56
回答 1查看 1.5K关注 0票数 1

我正在使用可可,我正在尝试为我正在编写的程序创建一个tcp socket服务器,我正在使用NSFileHandle和acceptConnectionInBackgroundAndNotify方法。我一直在遵循here上的代码。

我遇到的问题是,我可以连接我的客户端一次,但当我尝试再次连接时,我得到了一个连接被拒绝的错误。

在我第一次连接之前,命令sudo lsof -i -P返回以下信息:

代码语言:javascript
复制
RubyBeat  23964    pauljohnson    8u  IPv4 0x0632c274      0t0    TCP *:1234 (LISTEN)

在第一次与客户端连接之后,我得到了这样的结果:

代码语言:javascript
复制
RubyBeat  23964    pauljohnson    5u  IPv4 0x06a30334      0t0    TCP localhost:1234->localhost:51579 (CLOSED)

我的应用程序似乎没有重新打开套接字来侦听连接,在第一个套接字进入后,当我尝试第二次连接时,它得到了错误编号22。

我正在使用cocoa中的垃圾收集,我想知道这是否会导致套接字出现问题?

我的代码是:

代码语言:javascript
复制
    [self createSocket];
}

-(void)createSocket 
{
    // create socket and wait for events to come in
    NSSocketPort* serverSock = [[NSSocketPort alloc] initWithTCPPort: 1234];
    socketHandle = [[NSFileHandle alloc] initWithFileDescriptor: [serverSock socket]
                                                 closeOnDealloc: NO];

    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(newConnection:) 
                                                 name: NSFileHandleConnectionAcceptedNotification
                                               object: socketHandle];

    [socketHandle acceptConnectionInBackgroundAndNotify];
}

- (void)newConnection:(NSNotification*)notification
{
    NSLog(@"connection accepted");

    NSDictionary* userInfo = [notification userInfo];
    NSFileHandle* remoteFileHandle = [userInfo objectForKey:
                                      NSFileHandleNotificationFileHandleItem];

    if([[userInfo allKeys] containsObject:@"NSFileHandleError"]){
        NSNumber* errorNo = [userInfo objectForKey:@"NSFileHandleError"];
        if( errorNo ) {
            NSLog(@"NSFileHandle Error: %@", errorNo);
            return;
        }
    }

    [socketHandle acceptConnectionInBackgroundAndNotify];


    [[NSNotificationCenter defaultCenter] addObserver:self 
       selector: @selector(processSocketData:)
           name: NSFileHandleReadCompletionNotification
         object: remoteFileHandle];

    // Send a message to the client, acknowledging that the connection was accepted
    [remoteFileHandle writeData: [@"OK" dataUsingEncoding: NSASCIIStringEncoding]];

    [remoteFileHandle readInBackgroundAndNotify];
}

/*
 Handle client data
 */
- (void)processSocketData:(NSNotification *)note
{
    NSData *data = [[note userInfo]
                    objectForKey:NSFileHandleNotificationDataItem];

    NSNumber* errorNo = [[note userInfo] objectForKey:@"NSFileHandleError"];
    if( errorNo ) {
        NSLog(@"NSFileHandle Error: %@", errorNo);
        return;
    }

    // Do something here with your data

    // search string for \n\n that terminates event
    NSString* stringData = [[NSString alloc] initWithData: data encoding: NSASCIIStringEncoding];
    NSLog(@"data received: %@", stringData);

    NSDictionary* lastEvent = nil;

    NSRange range =  [stringData rangeOfString: @"\n\n"];

    if (range.location != NSNotFound) {
        NSArray* subStrings = [stringData componentsSeparatedByString:@"\n\n"];

        NSMutableArray* events = [[NSMutableArray alloc] init]; 

        [eventBuffer appendString: [subStrings objectAtIndex: 0]];

        // handle first event - could be in parts
        NSDictionary * json = (NSDictionary*)[eventBuffer JSONValue];

        [events addObject:json];

        for(int i = 1; i < [subStrings count]-1; i++){
            NSString* subString = [subStrings indexOfObject:i];

            NSDictionary * eventJson = (NSDictionary*)[subString JSONValue];

            [events addObject:eventJson];
        }

        // we have at least one event to draw here

        for(NSDictionary* event in events){
            NSLog(@"event: %@", [event objectForKey:@"type"]);
        }

        lastEvent = [events lastObject];

        // clear eventBuffer
        [eventBuffer setString:@""];

        // add end of data to eventBuffer?
    }else {
        [eventBuffer appendString:stringData];

    }

    // check event if it is a program exit event then stop receiving data

    if([[lastEvent objectForKey: @"type"] compare: @"exit"] != NSOrderedSame){
        // Tell file handle to continue waiting for data
        [[note object] readInBackgroundAndNotify];
    }else {


        NSLog(@"exit received stopping receiving data");
    }

}
EN

回答 1

Stack Overflow用户

发布于 2011-01-13 22:17:15

我以前遇到过这个问题。

读取完所有数据后,再执行一次“后台接受连接”,以进行另一轮读取数据。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4677724

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档