2011-01-13 11 views
1

私はココアを使用していますが、私が書いているプログラムのためのTCPソケットサーバーを作成しようとしています、NSFileHandleとメソッドacceptConnectionInBackgroundAndNotifyを使用しています。私はhereのコードに従っています。NSFileHandle関数acceptConnectionInBackgroundAndNotifyが2回目に呼び出されたときに動作しません

私はクライアントに一度接続することができますが、再度接続しようとすると接続が拒否されるという問題があります。

私が最初に接続する前に、コマンドはsudo lsofの-i -Pは、次の情報を返します。私はこれを取得、クライアントとの最初の時間を接続した後

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

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

私のアプリケーションは、最初の接続が入った後に接続を待ち受けるためにソケットを再オープンしていないようで、2度目の接続を試みるとエラー番号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

これは私のために働いてくれました、ありがとう! –

関連する問題