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ß.