2011-01-13 4 views
1

나는 코코아를 사용하고 있고 쓰고있는 프로그램 용 TCP 소켓 서버를 만들려고합니다. NSFileHandle과 acceptConnectionInBackgroundAndNotify 메서드를 사용하고 있습니다. 나는 here에서 코드를 따라 왔습니다.NSFileHandle 함수 acceptConnectionInBackgroundAndNotify 두 번째 호출 할 때 작동하지 않습니다

내가 가지고있는 문제는 클라이언트를 한 번 연결할 수 있지만 연결을 다시 시도하면 연결이 거부되는 오류가 발생합니다. 내가 -i -P lsof를 명령 sudo는 다음 정보를 반환 처음 연결하기 전에

: 클라이언트와 처음 연결 한 후

RubyBeat 23964 pauljohnson 8u IPv4 0x0632c274  0t0 TCP *:1234 (LISTEN) 

을 나는이 얻을 :

RubyBeat 23964 pauljohnson 5u IPv4 0x06a30334  0t0 TCP localhost:1234->localhost:51579 (CLOSED) 

내 응용 프로그램은 첫 번째 소켓이 들어온 후 소켓을 다시 열려고하지 않고 두 번째 연결하려고하면 오류 번호 22를 얻습니다.

코코아에서 가비지 수집을 사용하고 있는데 소켓에 문제가 있는지 궁금한가요?

내 코드는 다음과 같습니다

[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"); 
    } 

} 
+0

readInBackgroundAndNotify 대신 readInBackgroundAndNotify를 사용해보십시오. 나는 이것을했고 그것은 도왔다. –

답변

3

내가 전에이 문제를 만났다.
모든 데이터를 읽은 후에 다른 데이터 읽기를 위해 "백그라운드에서 연결 허용"을 수행하십시오.

+0

흠, 아직 작동하지 않았습니다. 아, 포기하고 C로 된 표준 소켓을 사용하여 작성했습니다. –

+1

이것은 나를 위해 일했습니다. 감사합니다! –

관련 문제