【问题标题】:Issues with MonoTouch and CFStream APIMonoTouch 和 CFStream API 的问题
【发布时间】:2012-09-19 08:38:16
【问题描述】:

我目前正在开发一个需要通过套接字连接与 MQTT 服务器通信的应用程序。由于 System.Net.Sockets API 在从 WiFi 网络切换到 3G 网络时往往会出现异常行为(实际上这种情况经常发生),我决定尝试使用 CFStream API。在这样做的过程中,我遇到了几个问题,如下所示。

使用 CreatePairWithSocketToHost 创建一对流,只要我在其中一个流上调用 Open(),应用程序就会崩溃。

CFStream.CreatePairWithSocketToHost(GetEndPoint(), out mReadStream, out mWriteStream);
mReadStream.EnableEvents(CFRunLoop.Current, CFRunLoop.CFDefaultRunLoopMode);
mWriteStream.EnableEvents(CFRunLoop.Current, CFRunLoop.CFDefaultRunLoopMode);
mReadStream.Open();
mWriteStream.Open();

无论我是否调用EnableEvents(),都会发生崩溃。例外是:

[ERROR] FATAL UNHANDLED EXCEPTION: MonoTouch.CoreFoundation.CFException: The operation couldn’t be completed. Cannot allocate memory
  at MonoTouch.CoreFoundation.CFStream.CheckError () [0x0000f] in /Developer/MonoTouch/Source/monotouch/src/shared/CoreFoundation/CFStream.cs:236 
  at MonoTouch.CoreFoundation.CFStream.Open () [0x00040] in /Developer/MonoTouch/Source/monotouch/src/shared/CoreFoundation/CFStream.cs:248 
  at TestCfNework.RootViewController.TestCreatePairToHost () [0x00041] in /Users/adrian/Projects/TestCfNework/TestCfNework/RootViewController.cs:79 
  at TestCfNework.RootViewController.ViewDidLoad () [0x00000] in /Users/adrian/Projects/TestCfNework/TestCfNework/RootViewController.cs:24 
  at MonoTouch.UIKit.UIWindow.MakeKeyAndVisible () [0x00008] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIWindow.g.cs:124 
  at TestCfNework.AppDelegate.FinishedLaunching (MonoTouch.UIKit.UIApplication app, MonoTouch.Foundation.NSDictionary options) [0x0002e] in /Users/adrian/Projects/TestCfNework/TestCfNework/AppDelegate.cs:32 
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38 
  at TestCfNework.Application.Main (System.String[] args) [0x00000] in /Users/adrian/Projects/TestCfNework/TestCfNework/Main.cs:17 

通过首先创建和连接CFSocket 来创建一对带有CreatePairWithSocket 的流允许Open() 继续进行而不会崩溃,但CanAcceptBytesEvent 永远不会被触发,CanAcceptBytes() 始终为假并且任何写入尝试都会失败超时。

mSocket = new CFSocket(AddressFamily.InterNetwork, 
    SocketType.Stream, 
    ProtocolType.Tcp, 
    CFRunLoop.Current);
mSocket.ConnectEvent += delegate {
    Console.WriteLine("Socket connected");

    CFStream.CreatePairWithSocket(mSocket, out mReadStream, out mWriteStream);
    mReadStream.EnableEvents(CFRunLoop.Current, CFRunLoop.CFDefaultRunLoopMode);
    mWriteStream.EnableEvents(CFRunLoop.Current, CFRunLoop.CFDefaultRunLoopMode);

    mReadStream.Open();
    mWriteStream.Open();

    mWriteStream.CanAcceptBytesEvent += delegate {
        Console.WriteLine("Write stream can now accept data");
    };
    mWriteStream.ErrorEvent += delegate {
        Console.WriteLine(mWriteStream.GetError());
    };
};
mSocket.Connect(GetEndPoint(), 0);

使用CreatePairWithPeerSocketSignature 创建一对流是唯一实际生成一对我可以使用的流:打开不会崩溃,我可以分别写入和读取。

API 在模拟器和实际设备上都以这种方式运行。那么,这是我做错了吗?是 MonoTouch 的问题吗?它是 CFStream API 本身的错误吗?

MonoTouch 版本:6.0.1。 XCode 版本:4.5。

【问题讨论】:

  • 很想知道您最终使用的是哪个 MQTT 库,或者您正在开发自己的库?
  • 两者,实际上:我目前正在使用这个库sourceforge.net/projects/mqttdotnet(尽管它需要在此过程中进行一些调整),同时我正在开发自己的。
  • 啊,是的,我猜这个库不符合 3.1 标准。希望在某个阶段看到您的图书馆,如果合适的话,很高兴在 mqtt.org 网站上列出。

标签: ios xamarin.ios ios-simulator cfstream cfsocket


【解决方案1】:

我在 MonoMac / MonoTouch 中编写了大部分 CFNetwork 代码,所以我希望能够帮助您:-)

您的代码在我看来没问题。它适用于 MonoMac(Mac 上的独立 Cocoa 应用程序),但我发现 MonoTouch 存在同样的问题。打开读取流有时有效,有时无效,打开写入流总是失败。

CFStream.CreatePairWithSocketToHost() 呼叫CFStreamCreatePairWithSocketToCFHost()

添加新的重载版本后:

    public static void CreatePairWithSocketToHost (string host, int port,
                                                   out CFReadStream readStream,
                                                   out CFWriteStream writeStream)

调用CFStreamCreatePairWithSocketToHost(),现在工作正常。

我刚刚看了这个,发现了问题,很快就会解决。

关于您的第二个问题,CFSocket API 在内部访问相同的代码路径,因此它也受到此错误的影响。

【讨论】:

【解决方案2】:

【讨论】:

  • 其实这是我尝试的第一件事,似乎并没有解决我最初的问题。这就是我最终尝试 CFStream API 的原因。
猜你喜欢
  • 2012-05-05
  • 2010-12-13
  • 2011-12-30
  • 1970-01-01
  • 2011-06-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多