2010-12-09 27 views
2

Ich mache Async Socket-Programmierung, und mein Code funktioniert die meiste Zeit, aber manchmal nicht. Das Wesentliche ist: Ich erstelle ein Socket-Paar, erzeuge Lese- und Schreib-Streams, und wenn ich etwas schreiben will, plane ich es in einer Run-Schleife eines separaten Threads. Wie so:CFWriteStreamScheduleWithRunLoop funktioniert manchmal, manchmal nicht?

CFStreamClientContext context = {0, sc, NULL, NULL, NULL}; 
if (CFWriteStreamSetClient(sc.writeStream, kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, myWriteStreamCallBack, &context)) { 
CFWriteStreamScheduleWithRunLoop(sc.writeStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); 
} 

... wo myWriteStreamCallback eine statische Funktion der richtigen Form ist ...

die Buchsen/Ströme wurden wie so geöffnet:

CFReadStreamRef readStream = NULL; 
CFWriteStreamRef writeStream = NULL; 

@try { 
    // create a pair of streams to the host and open them 

    CFStreamCreatePairWithSocketToCFHost(kCFAllocatorDefault, scomm.host, SERVER_PORT, &readStream, &writeStream); 
    if (readStream == NULL)  @throw [[[CommunicationReadStreamNotCreatedException alloc] init] autorelease]; 
    if (writeStream == NULL) @throw [[[CommunicationWriteStreamNotCreatedException alloc] init] autorelease]; 
    if (!CFReadStreamOpen(readStream)) @throw [[[CommunicationReadStreamNotOpenedException alloc] init] autorelease]; 
    if (!CFWriteStreamOpen(writeStream)) @throw [[[CommunicationWriteStreamNotOpenedException alloc] init] autorelease]; 
    ... 

Nun zum Problem : Dieser Code (und es gibt mehr, wenn es irgendjemandem hilft), ist größtenteils richtig, weil es meistens funktioniert. Aber manchmal kann ich am Anfang des Programms versuchen, einige Daten auf diese Weise zu senden, und der Callback für den Socket wird korrekt in die Run-Schleife gestellt, aber dann wird er nie aufgerufen. Später im Programm wird der gleiche Code mit einem anderen Socket ausgeführt, und der Callback wird aufgerufen (Sockets werden an dieselbe Adresse gesendet).

Ich weiß, das ist vage, aber bevor ich in den gesamten Code posten, hat jemand grobe Ideen über Dinge, die möglicherweise dazu führen könnten? Callbacks manchmal nicht auf Runloops aufgerufen werden, das ist.

Oh ja, ich sollte hinzufügen, dass dies offensichtlich eine Art von Race-Condition ist - ich kann das Problem unzuverlässig machen, indem ich Logging-Anweisungen an den richtigen Stellen hinzufüge. Und dann funktioniert es manchmal und manchmal nicht, mit genau dem gleichen Code. Spaß Spaß.

Antwort

1

erhielt ich eine Lösung aus „quinn den Eskimos“ auf den Apfel Foren:

Das Problem Auflösung des Host in einem Thread und die CFHostRef in anderen Threads verwendet getan war. Das ist schlecht.

CFHost Erstellung im selben Thread (das Objekt scomm.host, oben) behebt das Problem.

Verwandte Themen