gpt4 book ai didi

ios - MonoTouch 和 CFStream API 的问题

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:48:29 26 4
gpt4 key购买 nike

我目前正在开发一个需要通过套接字连接与 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() 都会发生崩溃。异常(exception)情况是:

[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 也有同样的问题。打开读流有时可以,有时不能,打开写流总是失败。

CFStream.CreatePairWithSocketToHost() 调用 CFStreamCreatePairWithSocketToCFHost()

添加新的重载版本后:

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

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

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

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

关于ios - MonoTouch 和 CFStream API 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12623429/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com