sockets - CFWriteStreamScheduleWithRunLoop 有时有效,有时无效?

标签 sockets ios runloop

我正在做异步套接字编程,我的代码大部分时间都能正常工作,但有时却不能。要点是:我创建一个套接字对,创建读写流,然后当我想写一些东西时,我将它安排在一个单独线程的运行循环上。像这样:

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];
  ...

现在问题来了:这段代码(还有更多代码,如果它对任何人有帮助的话)大部分是正确的,因为它大部分都有效。然而,有时,在程序的最开始,我可以尝试以这种方式发送一些数据,套接字的回调将正确地放置在运行循环中,但它永远不会被调用。在程序的后面,相同的代码将与另一个套接字一起运行,回调将被调用(套接字转到相同的地址)。

我知道这很模糊,但在我开始发布所有代码之前,有人对可能导致这种情况的事情有任何粗略的想法吗?也就是说,回调有时不会在运行循环中被调用。

哦,是的,我应该补充一点,这显然是某种类型的竞争条件 - 我可以通过在正确的位置添加日志语句来不可靠地解决问题。然后,它有时有效,有时无效,使用完全相同的代码。好玩好玩。

最佳答案

我从苹果论坛上的“quinn the eskimo”获得了一个解决方案:

问题是主机解析在一个线程中完成,而 CFHostRef 在其他线程中使用。这是不好的。

CFHost 在同一个线程中创建(上面的 scomm.host 对象)修复了问题。

关于sockets - CFWriteStreamScheduleWithRunLoop 有时有效,有时无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4400772/

相关文章:

android - 超过3g的android中的套接字编程

ios - 从 AppDelegate 更改另一个文件中的变量

core-data - Core Data 可以使用 Google Docs 作为持久性存储吗?

ios - 找出 iOS 中什么阻塞了主线程/运行循环?

java - java中的Socket.getInputStream().read()方法会做什么?

c# - 如何在 Socket 类中使用动态端口?

python - 我应该使用 epoll 还是只在线程中阻塞 recv?

iphone - 在 Xcode 中重命名事件处理程序的最简单方法是什么?

objective-c - Cocoa GUI 类如何在不调用 NSApplication 或 NSRunLoop 的情况下运行

c# - 用于将来在当前线程上执行代码的 PostMessage 的 C# 等效项是什么?