我正在做异步套接字编程,我的代码大部分时间都可以工作,但有时却不行。要点是:我创建一个套接字对,创建读写流,然后当我想写一些东西时,我将它安排在一个单独线程的运行循环上。像这样:
CFStreamClientContext context = {0, sc, NULL, NULL, NULL};
if (CFWriteStreamSetClient(sc.writeStream, kCFStreamEventCanAcceptBytes | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered, myWriteStreamCallBack, &context)) {
CFWriteStreamScheduleWithRunLoop(sc.writeStream, CFRunLoopGetCurrent(), kCFRunLoopCommonModes);
}
...其中 myWriteStreamCallback 是正确形式的静态函数...
套接字/流的打开方式如下:
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];
...
现在问题来了:这段代码(还有更多,如果它对任何人有帮助的话)大部分是正确的,因为它大部分都有效。但是,有时,在程序的最开始,我可以尝试以这种方式发送一些数据,并且套接字的回调将正确地放置在运行循环中,但它永远不会被调用。稍后在程序中,将使用另一个套接字运行相同的代码,并且将调用回调(套接字转到相同的地址)。
我知道这很模糊,但是在我发布所有代码之前,是否有人对可能导致这种情况的事情有任何粗略的想法?回调有时不会在运行循环上被调用,也就是说。
哦,是的,我应该补充一点,这显然是某种类型的竞争条件——我可以通过在正确的位置添加日志语句来不可靠地解决问题。然后,它有时工作,有时不工作,使用完全相同的代码。好玩。