2016-07-08 8 views
0

Hallo in meiner iOS Swift-Anwendung, die ich einen Live-Stream anzeigen.CFSocketSetAddress Bind Fehler: 48 nach Wiedereröffnung Stream

Deshalb habe ich diese Funktion geschaffen, den Strom zu starten, die aufgerufen wird, wenn eine bestimmte containerView geladen wird:

func startStream() { 

    let masterViewController = self.parentViewController as? MasterViewController 

    let ip = RTPTools().findLocalWifiIp() 
    print("local IP: \(ip)") 

    let view = masterViewController!.streamView 
    view.waiting = true 

    masterViewController!.receiver = RTPReceiver(localIp: ip, listenPort: 5000) 
    masterViewController!.receiver!.delegate = view 
    view.setNeedsDisplay() 

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(MasterViewController.decodingFailed(_:)), name: AVSampleBufferDisplayLayerFailedToDecodeNotification, object: self.view.layer) 

    Connector.sharedInstance.runLivePreview() 

    masterViewController?.showStreamView() 
} 

ich diese Methode in der viewDidAppear Funktion aufrufen und die Benachrichtigungsfunktionen wie dieser Einstellung :

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 

    NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(InformationsViewController.restartStream), name: UIApplicationWillEnterForegroundNotification, object: nil) 
    NSNotificationCenter.defaultCenter().addObserver(self, selector:#selector(InformationsViewController.clearStream), name: UIApplicationWillResignActiveNotification, object: nil) 

    startStream() 
} 

Die Clearstream- und restartStream Funktionen suchen wie folgt aus:

func clearStream() { 
    let masterViewController = self.parentViewController as? MasterViewController 
    masterViewController!.receiver = nil 

    Connector.sharedInstance.stopLivePreview() 
} 

func restartStream() { 
    let masterViewController = self.parentViewController as? MasterViewController 

    let ip = RTPTools().findLocalWifiIp() 
    print("local IP: \(ip)") 

    let view = masterViewController!.streamView 
    view.waiting = true 

    masterViewController!.receiver = RTPReceiver(localIp: ip, listenPort: 5000) 
    masterViewController!.receiver!.delegate = view 
    view.setNeedsDisplay() 

    let videoLayer = view.layer as! AVSampleBufferDisplayLayer 
    videoLayer.flushAndRemoveImage() 

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(MasterViewController.decodingFailed(_:)), name: AVSampleBufferDisplayLayerFailedToDecodeNotification, object: self.view.layer) 

    Connector.sharedInstance.runLivePreview() 

    masterViewController?.showStreamView() 
} 

Die Sache ist, dass, wenn ich auf die Home-Taste klicke, während der Stream läuft und dann zurück zur Anwendung geht alles beginnt und gut funktioniert. Aber ich bekomme den CssocketSetAddress Bind Fehler: 48 Fehler, wenn ich die Ansicht zu einer anderen Ansicht wechseln und dann zurück zu der Ansicht wechseln, wo der Stream ausgeführt wird.

Die RTPReceiver werden wie folgt umgesetzt:

@implementation RTPReceiver 

- (id) initWithLocalIp:(NSString*)ip listenPort:(uint16_t)port { 
    self = [super init]; 
    if (!self) { 
     return nil; 
    } 
    self.localIp = ip; 
    self.listenPort = port; 

    //create socket 
    CFSocketContext socketContext = {0, (__bridge void*)self, NULL, NULL, NULL}; 
    CFSocketRef socket = CFSocketCreate(NULL, PF_INET, SOCK_DGRAM, IPPROTO_UDP, 
           kCFSocketDataCallBack , MySocketCallback, &socketContext); 
    NSAssert(socket, @"Socket creation failed"); 
    self.socket = socket; 
    CFRelease(socket); 

    //set address 
    struct sockaddr_in addr; 
    memset(&addr, 0, sizeof(addr)); 
    addr.sin_len = sizeof(addr); 
    addr.sin_family = AF_INET; 
    addr.sin_addr.s_addr = inet_addr([self.localIp cStringUsingEncoding:NSASCIIStringEncoding]); 
    addr.sin_port = htons(self.listenPort); 
    NSData* address = [NSData dataWithBytes:&addr length: sizeof(addr)]; 

    // HERE IS THE ERROR 
    CFSocketError sockErr = CFSocketSetAddress(self.socket, (CFDataRef) address); 
    NSAssert(sockErr == kCFSocketSuccess,@"Set socket address failed"); 

    //add to run loop 
    CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, self.socket, 0); 
    CFRunLoopAddSource(CFRunLoopGetMain(), source, kCFRunLoopCommonModes); 
    CFRelease(source); 
    return self; 
} 

Ich verstehe nicht, warum ich diese Fehlermeldung erhalten, während ich den gleichen Prozess machte den Strom zu starten. Kann mir jemand helfen?

Antwort

0

Ich finde auch eine Lösung.

Warum Sie nicht unten verwenden statt CFSocketSetAddress

if (0 != (err = bind(sock, (struct sockaddr *)&addr, sizeof(addr)))) { 
     NSLog(@"Bind error"); 
     return false; 
    } 

Da in Dokumenten,

Diese Funktion bindet den Socket durch bind, und wenn der Socket unterstützt, konfiguriert die Buchse für das hören von mit einem Rückstand von 256.

mit binden hören Aufruf funktioniert für mich und jetzt finde ich auch eine Möglichkeit, CFSocketSetAddress zu verwenden.

Verwandte Themen