2

私は非同期ソケット プログラミングを行っていますが、ほとんどの場合、コードは機能しますが、機能しない場合もあります。要点は次のとおりです。ソケット ペアを作成し、読み取りストリームと書き込みストリームを作成します。次に、何かを書きたい場合は、別のスレッドの実行ループでスケジュールします。そのようです:

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

ここで問題があります: このコード (そして、それが誰かの役に立てばもっとあります) は、ほぼ正しく動作します。ただし、プログラムの最初の段階で、この方法でデータを送信しようとすると、ソケットのコールバックが実行ループに正しく配置されることがありますが、呼び出されることはありません。プログラムの後半で、同じコードが別のソケットで実行され、コールバックが呼び出されます (ソケットは同じアドレスに移動します)。

これが漠然としていることはわかっていますが、すべてのコードを投稿する前に、これを引き起こす可能性のあることについて大まかなアイデアを持っている人はいますか? つまり、ランループでコールバックが呼び出されないことがあります。

そうそう、これは明らかにある種の競合状態であることを付け加えておく必要があります。適切な場所にログ ステートメントを追加することで、問題を確実に解消することができます。そして、まったく同じコードで、機能する場合と機能しない場合があります。楽しい楽しいです。

4

1 に答える 1

1

Apple フォーラムの「エスキモーのクイン」から解決策を入手しました。

問題は、1 つのスレッドで実行され、他のスレッドで使用されるホストの解決でしたCFHostRef。これは悪いです。

CFHost同じスレッド (scomm.host上記のオブジェクト) で作成を行うと、問題が修正されます。

于 2010-12-12T04:55:12.577 に答える