私は現在、ソケット接続を介してMQTTサーバーと通信する必要があるアプリケーションを開発しています。System.Net.Sockets APIは、WiFiネットワークから3Gネットワークに切り替えるときに誤動作する傾向があるため(これは実際には非常に多く発生します)、CFStreamAPIを試してみることにしました。そうすることで、私は次のようないくつかの問題に遭遇しました。
ストリームのペアを作成すると、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
CreatePairWithSocket
最初にを作成して接続するCFSocket
ことでストリームのペアを作成すると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。