2012-03-14 14 views
0

私はサーバーとして動作している.NETデスクトッププログラムを持っていますが、私は自分のクライアントプログラムのポートをiOSに実装しようとしていますが、NSSocketから奇妙な動作があります。ここにサーバーからの関連コードがあります。iOSと.NETのソケットの問題?

public NetworkListener() 
{ 
    _Stream = new MemoryStream(); 
    _tcpServer = new TcpListener(System.Net.IPAddress.Any, 8086); 
    _endPoints = new List<EndPoint>(); 
} 

public void BeginListening() 
{ 
    _tcpServer.Start(); 
    _workerThread = new Thread(new ThreadStart(WorkerLoop)); 
    _workerThread.IsBackground = true; 
    _workerThread.Start(); 
} 

private void WorkerLoop() 
{ 
    while(true) 
    { 
     _clientSocket = _tcpServer.AcceptSocket(); 
     _networkStream = new NetworkStream(_clientSocket, true); 
     /* ... rest of method here ... */ 
    } 
} 

私はXCodeの4.2を使用してiOSSimulatorに次のコードをしようとすると、シミュレータはサーバプログラムと同じネットワーク上にあると私は使用するJavaクライアントを実行することができますホスティングのイオス5.マックをターゲットにしています同じハードコーディングされたローカルIPを接続するだけです。 Objective Cコードでは、いくつかのデータを受け取ってNSDataメンバープロパティに格納しています。そして、Socketが開かれたら、ストリームコールバックを使っていつデータを送信するか教えてください。 XCodeのコンソールで

- (IBAction)connectToServer 
{ 
    NSURL *serverUrl = [NSURL URLWithString:@"10.0.0.5"]; 

    CFReadStreamRef readStream; 
    CFWriteStreamRef writeStream; 
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)[serverUrl host], 8086, &readStream, &writeStream); 

    [self setInStream:(NSInputStream *)readStream]; 
    [self setOutStream:(NSOutputStream *)writeStream]; 
    [self.inStream setDelegate:self]; 
    [self.outStream setDelegate:self]; 
    [self.inStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [self.outStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [self.inStream open]; 
    [self.outStream open]; 

    NSError *error = [self.outStream streamError]; 
    if (error) { 
     NSLog(@"outstream error: %@", [error localizedDescription]); 
    } 
} 

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode 
{ 
    NSError *error; 
    if ([aStream isEqual:outStream]) { 
     switch (eventCode) { 
      case NSStreamEventHasSpaceAvailable: 
       NSLog(@"Stream has space!"); 
       [self writeDataToStream]; 
       break; 
      case NSStreamEventOpenCompleted: 
       NSLog(@"Stream is open!"); 
       break; 
      case NSStreamEventErrorOccurred: 
       error = [self.outStream streamError]; 
       NSLog(@"Stream error occured: %@", [error localizedDescription]); 
       break; 
      default: 
       break; 
     } 
    } 
} 

- (void)writeDataToStream 
{ 
    unsigned int byteIndex = 0; 
    unsigned int length = data.length; 
    uint8_t *buffer = (uint8_t *)[data bytes]; 

    while (byteIndex <= length) {  
     unsigned int bufferLength = (length - byteIndex >= 1024) ? 1024 : (length - byteIndex); 
     uint8_t tempBuffer[bufferLength]; 

     (void)memcpy(tempBuffer, buffer, bufferLength); 
     if (self.outStream.hasSpaceAvailable) { 
      bufferLength = [self.outStream write:tempBuffer maxLength:bufferLength]; 
      byteIndex += bufferLength; 
     } else 
      NSLog(@"Stream is blocked!"); 
    } 
} 

、私は「ストリームが開いている!」を参照してください、「ストリームは、スペースを持っている!」、と言う例外に続く「操作を完了できませんでした。不正なファイルディスクリプタを」が続きます。 _tcpServer.AcceptSocket()の直後にサーバーコードにブレークポイントを設定しましたが、決してヒットしません。ストリームが開きますが、ソケットは決して接続されていないようです。

+0

あなたは示していませんでしたが、実際に何かをソケットに書き込んだかどうか確認しましたか?もしそうでなければ、bufferLength変数は-1になります。これは、(バイトインデックスが長さより大きくならないために)連続してループします。長さ(byteIndex)が1未満になり、クッキーを投げていると思われます。 –

+0

ネットワークアプリケーションで役立つもう1つのことは実行することですパケットスニッファ(wireshark、さらにはCocoaPacketAnalyzer)が大いに役立ちます。それで、何かがうまくいかない理由を推測する必要はありません。 –

答えて

-1

[serverUrl host]がnilであるかどうかを確認してください。

この問題も発生しました。そのため、IPアドレス(URLWithString:@"http://10.0.0.5")の前にhttp://というプロトコル文字列を追加しました。

+0

彼はhttpプロトコルを使用していないので、httpプレフィックスを追加する必要はありません。 – fyasar

+0

誤ってNSURLにエラーがない可能性があります(参考:developer.apple.com/library/mac/#documentation/Cocoa/Reference/...セクション「Handling Object Creation Failure」、RFCに準拠する必要があります)。ファイルパスは2396、HTTP URLはRFC 1808でスキームを指定してください)そうでない場合はCFStringまたはNSStringを作成してください。スキームなしでCFURLまたはNSURLを使用している場合は、nilを取得する可能性が高くなります。 – morph85