12

Apple の Web サイトからWiTapコードをダウンロードしました。ローカル Wi-Fi ネットワーク経由でデータを転送するためのものです。クライアント - サーバー アーキテクチャとして対話するプロジェクトに取り組んでいます。クライアント側からサーバーに NSData を送信しています。

2 つのプロジェクトを作成しました。1 つはクライアント用、もう 1 つはサーバー用

クライアント側のプロジェクトで、次の変更を行いました。そのために、次のメソッドを追加してAppController.mファイルを変更しました。

AppController.m (クライアント側)

- (void)sendData:(NSData*)pobjData
{
    assert(self.streamOpenCount == 2);

    if ( [self.outputStream hasSpaceAvailable] ) 
    {
        NSInteger   bytesWritten;

        NSUInteger length = [pobjData length];

        bytesWritten = [self.outputStream write:[pobjData bytes] maxLength:[pobjData length]];

        NSLog(@"written bytes -> %d",bytesWritten);
    }
}

次に、このメソッドを呼び出してデータを送信します。

サーバー側のプロジェクトでは、次のメソッドを変更して AppController.m ファイルを変更したため、次の変更を加えました。

AppController.m (サーバー側)

- (void)stream:(NSStream *)stream handleEvent:(NSStreamEvent)eventCode
{
    #pragma unused(stream)

    switch(eventCode) {

        case NSStreamEventOpenCompleted: {
            self.streamOpenCount += 1;
            assert(self.streamOpenCount <= 2);

            // Once both streams are open we hide the picker and the game is on.

            if (self.streamOpenCount == 2) {
                [self dismissPicker];

                [self.server deregister];
            }
        } break;

        case NSStreamEventHasSpaceAvailable: {
            assert(stream == self.outputStream);
            // do nothing
        } break;

        case NSStreamEventHasBytesAvailable:
        {
            if (stream == self.inputStream)
            {

                NSInteger bytesRead;
                uint32_t buffer[32768];

                NSMutableData *_data = [NSMutableData data];

                // Pull some data off the network.
                bytesRead = [self.inputStream read:buffer maxLength:sizeof(buffer)];
                if (bytesRead == -1) {

                } else if (bytesRead == 0) {

                } else {
                    // FIXME: Popup an alert

                    const long long expectedContentLength = bytesRead;
                    NSUInteger expectedSize = 0;

                    // expectedContentLength can be represented as NSUInteger, so cast it:
                    expectedSize = (NSUInteger)expectedContentLength;

                    [_data appendBytes:buffer length:expectedSize];

                    NSLog(@"\"Data received has length: %d", _data.length);

                    [self performSelector:@selector(getData:) withObject:_data afterDelay:1.0];
                }
            }
        }
            break;

        default:
            assert(NO);
            // fall through
        case NSStreamEventErrorOccurred:
            // fall through
        case NSStreamEventEndEncountered: {
            [self setupForNewGame];
        } break;
    }
}

受信したデータをファイルとして書き込むメソッドを追加

     #define kUserDirectoryPath NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)

-(void)getData:(NSMutableData *)pData
{
                NSFileManager *tmpmanager = [NSFileManager defaultManager];
                [tmpmanager createFileAtPath:[AppController getDocumentDirectoryPath:[NSString stringWithFormat:@"%@.png",[NSDate date]]] contents:pData attributes:nil];
}


+(NSString*)getDocumentDirectoryPath:(NSString*)pStrPathName
{
            NSString *strPath=nil;

            if(pStrPathName)
                strPath = [[kUserDirectoryPath objectAtIndex:0] stringByAppendingPathComponent:pStrPathName];

            return strPath;
}

.png ファイルを NSData に変換し、クライアント側からサーバー側に送信します。サーバーがファイルをドキュメント ディレクトリにダウンロードします。

問題は、クライアント側からファイルを転送すると、サーバー側のドキュメント ディレクトリにダウンロードされることです。小さなファイルの場合、すべてが正常に機能します。ファイル サイズが 8kB を超えると、ドキュメント ディレクトリに書き込まれたファイルが破損します。

大きなファイルを送信できるようにしてください。

4

3 に答える 3

1

問題は、使用可能なすべてのデータを最後まで収集するためにコードがループしないことです (または、すべてのデータを送信するためにループします)。したがって、データの最初のバッファーのみを受け取ります。画像が小さい場合は問題なく動作しますが、画像が大きい場合は問題ありません。

NSMutableDataすべてのデータが送信されるまでバッファー スペースがある場合は送信し続け、ストリームの最後に到達するまで (ローカル変数ではなくインスタンス変数に)データを読み取り続けるように、コードを記述する必要があります。

于 2013-04-22T22:32:39.340 に答える
0

からダウンロードできる AsyncSocket を使用できます。

https://github.com/roustem/AsyncSocket

これは、CFSocket と CFNetwork で構築された Objective-C ラッパーであり、ローカル wifi で TCP/UDP プロトコルを使用して大量のデータ転送を処理できます。

ここでウィキを見つけることができますhttps://github.com/darkseed/cocoaasyncsocket/wiki/iPhone

クラスは非常にシンプルで実装が簡単です。試してみてください

于 2013-04-05T09:33:39.937 に答える
-1

システムの IP アドレスを配置する必要がある場所から Web サービスを作成しました。ファイルを送信する場所です。その後、入力した IP アドレスに接続できたら、ファイルを Base64 および NSData 形式で送信できます。

于 2013-04-25T05:22:28.347 に答える