MonoTouch和CFStream API的问题



我目前正在开发一个需要通过套接字连接与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()始终为false,并且任何写入尝试都会超时失败。

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。

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

你的代码在我看来还可以。它在MonoMac(Mac上的独立Cocoa应用程序)上运行得很好,但我在MonoTouch上看到了同样的问题。打开读流有时有效,有时无效,打开写流总是失败。

CCD_ 9调用CCD_。

添加新的重载版本后:

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

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

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

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

要唤醒3G网络,您需要使用:

http://iosapi.xamarin.com/?link=T%3aMonoTouch.ObjCRuntime.Runtime%2fM%2fStartWWAN

相关内容

  • 没有找到相关文章

最新更新