2011-02-10 3 views
2

을 얻고 있지. 내 응용 프로그램에서는 사용자가 최대 4 채널의 데이터 전송을 설정할 수 있습니다. 채널에서 특정 것이 무엇인지 알 수 없으므로 "시도"라고합니다. 지금까지 시뮬레이터에서만 테스트 중이며 UDP로만 작업하고 있습니다. 각 시험의 경우, 내가 (시뮬레이터 경우에 SimSocket라고, 전송 게시자 또는 가입자로 초기화 또는 각각 수신) 내 소켓 드라이버 클래스, 데이터의 상대적으로 적은 양의 송/수신의 새로운 인스턴스를 초기화 한 후 소켓을 닫고 해제 SimSocket. 그때, 수신기로 시험 # 0을 설정 127.0.0.1로 데이터를 전송하는 시험 # 1을 설정 : 그럼아이폰 UDP 리스너/서버 - 나는 내가 CF 소켓에서 데이터 콜백을 받고 있지 않다 문제는 데이터 콜백

여기

가 실패하는 방법이다 등, 등, 또 다른 재판을한다. 수신기를 시작한 다음 발신자와 데이터 전송이 정상적으로 작동합니다. 나는이 문제를 반복해서 반복 할 수있다. 그런 다음 IP 또는 포트 주소 나 패킷 크기 또는 패킷 속도를 변경하지 않고 데모 1 만 실행하면 데이터가 ether 또는 어딘가로 전송됩니다. 이런 일이 발생하면 내 콘솔 출력에 문제가 표시되지 않습니다. 다음으로 수신자를 다시 시작합니다. 0 번 시도한 다음 1 번 전송 인을 실행합니다. 그러나 지금은 데이터 콜백을 전혀 볼 수 없으며 0 번 시도에서는 처리 할 데이터가 전혀 없습니다. 내 질문은 왜 재판 0 해당 시퀀스 후 데이터를받지 못합니다?

일부 지원 정보는 .... 나는 루프백 인터페이스보고 Mac에서 Wireshark를 실행합니다. 심지어 시행 0이 실패한 실행에서도 Wireshark에서 볼 수있는 UDP 데이터 그램을 계속 볼 수 있습니다. 위에서 설명한 전체 시퀀스의 경우 콘솔 출력에서 ​​소켓이 항상 열리고 닫혀 있는지 알 수 있습니다 (마지막 시도 0은 실패합니다 - 물론 닫히지는 않습니다.). 모든 수신 코드가 주 스레드에서 실행 중입니다. 일련의 데이터를 보낼 때 별도의 스레드에서 처리하지만 작업이 진행될 때와 실행되지 않을 때 동일합니다. 2 Kbps에서 원시 데이터의 10 개의 50 바이트 '패킷'을 보낼 때이 오류가 발생할 수 있습니다.

다음은 내 SimSocket 구현 파일의 관련 부분입니다. 당신이 제공 할 수있는 도움에 감사드립니다. 감사.

#import "SimSocket.h" 

void simReceivedDataCallback(CFSocketRef s, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) { 
    // NOTE: I don't know if I'm accessing the address argument properly here, or if it contains useful information! 
    NSLog(@"SimSocket: simReceivedDataCallback function entry. Socket=%d, address=%s, port=%d", CFSocketGetNative(s), inet_ntoa(((struct sockaddr_in *)address)->sin_addr), htons(((struct sockaddr_in *)address)->sin_port)); 
     // send data to SimSocket delegate here 
} 

@implementation SimSocket 

@synthesize readyToUse, delegate, errors; 

- (id)initWithType:(SimSocketConnection)connectionType1 host:(NSString *)host1 port:(int)port1 { 
    if (self = [super init]) { 
     hostStr = host1; 
     port = port1; 
     isPublish = YES; 
     connectionType = connectionType1; 
     readyToUse = NO; 

     int sockType = (connectionType == SimSocketConnectionTcp) ? SOCK_STREAM : SOCK_DGRAM; 
     sockfd = socket(AF_INET, sockType, 0); 
     if (sockfd == -1) { 
      NSLog(@"SimSocket:initWithType: Error with socket() - %s", strerror(errno)); 
      return self; 
     } 

     memset((void *)&address_in, 0, sizeof(address_in)); 
     address_in.sin_family = AF_INET; 
     address_in.sin_port = htons(port); 
     address_in.sin_addr.s_addr = inet_addr([hostStr UTF8String]); 
     addressData = [NSData dataWithBytes:&address_in length:sizeof(address_in)]; 

     readyToUse = YES; 
     return self; 
    } 
    else { 
     return nil; 
    } 
} 

- (id)initPublishWithType:(SimSocketConnection)connectionType1 host:(NSString *)host1 port:(int)port1 { 
    if ([self initWithType:connectionType1 host:host1 port:port1]) { 
     readyToUse = NO; 
     NSLog(@"SimSocket:initPublishWithType: Successfully created BSD socket - %d", sockfd); 

     cfsocket = CFSocketCreateWithNative(NULL, sockfd, kCFSocketConnectCallBack, simCallback, NULL); 
     if (cfsocket == NULL) { 
     NSLog(@"SimSocket:initPublishWithType: Error with CFSocketCreateWithNative()"); 
     return self; 
     } 
     readyToUse = YES; 
    } 
    return self; 
} 

- (id)initSubscribeWithType:(SimSocketConnection)connectionType1 host:(NSString *)host1 port:(int)port1 delegate:(id <SimSocketEvents>)delegate1 { 
    NSLog(@"SimSocket:initSubscribeWithType: starting initialization with delegate %@", delegate1); 

    if ([self initWithType:connectionType1 host:host1 port:port1]) { 
     readyToUse = NO; 
     NSLog(@"SimSocket:initSubscribeWithType: Successfully created BSD socket - %d", sockfd); 

     delegate = delegate1; 
     address_in.sin_addr.s_addr = htonl(INADDR_ANY); 
     addressData = [NSData dataWithBytes:&address_in length:sizeof(address_in)]; 

     int yes = 1; 
     if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { 
      NSLog(@"SimSocket:initSubscribeWithType: Error with setsockopt() with SO_REUSEADDR - %s", strerror(errno)); 
     } 

     if (bind(sockfd, (struct sockaddr*) &address_in, sizeof(address_in)) == -1) { 
      NSLog(@"SimSocket:initSubscribeWithType: Error with bind() - %s", strerror(errno)); 
      errors = [NSString stringWithFormat:@"Bind Failed - %s. Try using a Different Port number.", strerror(errno)]; 
      close (sockfd); 
      return self; 
     } 

     CFSocketContext context = { 0, (void *)self, NULL, NULL, NULL }; 

     // TCP 
     if (connectionType == SimSocketConnectionTcp) { 
      if (listen(sockfd, 10) == -1) { 
       NSLog(@"SimSocket:initSubscribeWithType: Error with listen() - %s", strerror(errno)); 
       return self; 
      } 
      cfsocket = CFSocketCreateWithNative(NULL, sockfd, kCFSocketAcceptCallBack, simAcceptCallback, &context); 
     } 
     // UDP 
     else if (connectionType == SimSocketConnectionUdp) { 
      cfsocket = CFSocketCreateWithNative(NULL, sockfd, kCFSocketDataCallBack, simReceivedDataCallback, &context); 

     } 

     if (cfsocket == NULL) { 
      NSLog(@"SimSocket:initSubscribeWithType: Error with CFSocketCreateWithNative()"); 
      return self; 
     } 

     CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(NULL, cfsocket, 0); 
     CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode); 
     CFRelease(source); 
     NSLog(@"SimSocket:initSubscribeWithType: Current run loop = %x. Main thread run loop = %x.", CFRunLoopGetCurrent(), CFRunLoopGetMain()); 

     readyToUse = YES; 
     NSLog(@"SimSocket:initSubscribeWithType: Completed socket initialization successfully."); 
    } 
    return self; 
} 

- (void)dealloc { 
    if (cfsocket) CFRelease(cfsocket); 
    if (sockfd != -1) close(sockfd); 
    [errors release]; 
    [super dealloc]; 
} 

-(void)shutdown 
{ 
    NSLog(@"SimSocket: shutdown: Am shutting down the socket. sockfd = %d", sockfd); 
    if (cfsocket) CFRelease(cfsocket); 
    if (sockfd != -1) close(sockfd); 
} 

- (void)sendBytes:(const void *)bytes length:(int)length { 
    if (!readyToUse) { 
     NSLog(@"SimSocket:sendBytes: socket not ready to use for sending"); 
     return; 
    } 

    int bytesSent; 
    if (connectionType == SimSocketConnectionTcp) { 
     bytesSent = send(sockfd, bytes, length, 0); 
    } 
    else { 
     bytesSent = sendto(sockfd, bytes, length, 0, (struct sockaddr *)&address_in, sizeof(address_in)); 
    } 

    if (bytesSent < 0) { 
     NSLog(@"SimSocket:sendBytes: Oops, error- %s. No bytes sent.", strerror(errno)); 
    } 
    else if (bytesSent < length) { 
     NSLog(@"SimSocket:sendBytes: Oops, error- %s. Only %i sent out of %i", strerror(errno), bytesSent, length); 
    } 
    else { 
     NSLog(@"SimSocket:sendBytes: Successfully sent the packet (%d bytes) to %s", length, inet_ntoa(address_in.sin_addr)); 
    } 
    NSLog(@"SimSocket:sendBytes: Current run loop = %x. Main thread run loop = %x.", CFRunLoopGetCurrent(), CFRunLoopGetMain()); 
} 

@end 

답변

3

여러분,이 문제를 발견 한 것 같습니다. 상황을 막을 때 나는 CFSocket 만 공개했다. UDPEcho 샘플 프로젝트의 리드에 따라, 나는 이것을 CFSocketInvalidate 호출, CFRelease 호출, 그리고 CFSocket 참조를 NULL로 세 단계로 대체했다. 지금은 잘 작동하고있는 것 같습니다.

+0

이 대답은 나에게 허용됩니다. 그러나 나는 그것을 받아들이는 방법을 보지 못했다. FAQ에 언급 된 "대답의 왼쪽에있는 확인란 개요"가 표시되지 않습니다. – BillC

+0

BillC, 이름이 같은 두 개의 다른 계정이있는 것으로 보입니다. 두 가지 다른 평판 포인트와 두 개의 서로 다른 사용자 프로필 (사용자 611823 및 496092)으로 확인할 수 있습니다. 611823 계정으로 로그인하면 답을 수락 할 수 있습니다.) – gog

관련 문제