0

asyncsocket サンプルを出発点として使用して、iPhone での WLAN 通信について学習します。

Mac 上でサンプル サーバーを起動し、ポート 0 を開きます。Mac 上で実行されているテスト クライアントでデータを書き込むことができるため、これは機能します。

iPhoneでは、「ストリームが接続されました」がYESを返すので、なんとか接続できたと思います。

次に、syncsocket でデータを送信したいと思います: (完全なコードを含む編集バージョン)

import "InterfaceTestAppDelegate.h" import "InterfaceTestViewController.h" import "AsyncSocket.h" import "SyncSocket.h"

@implementation InterfaceTestAppDelegate

@synthesize window; @synthesize viewController;

  • (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)remoteHost port:(UInt16)remotePort { NSLog(@"Socket is connected!");

    NSLog(@"Remote Address: %@:%hu", remoteHost, remotePort);

    NSString *localHost = [sock localHost]; UInt16 localPort = [sock localPort];

    NSLog(@"Local Address: %@:%hu", localHost, localPort); }

  • (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSLog(@"application:didFinishLaunchingWithOptions:");

    /* asyncSocket = [[AsyncSocket alloc] initWithDelegate:self];

            NSError *err = nil;
                if (![asyncSocket connectToHost: @"192.168.0.30" onPort: 1234 error: &err])
                {
                    NSLog(@"Error connecting: %@", err);
                }
        NSData *data = [@"testxyz" dataUsingEncoding:NSUTF8StringEncoding];
    
        NSLog(@"trace 1");
        [asyncSocket writeData:data withTimeout:10 tag:0];
        NSLog(@"trace 2");
    

    */ syncSocket = [[SyncSocket alloc] initWithTimeout: 10]; syncSocket.nsLog = YES; if (![syncSocket connectToHost: @"192.168.0.30" onPort: 12345]) { NSLog(@"Error connecting syncSocket:"); } NSData *data = [@"testxyz" dataUsingEncoding:NSUTF8StringEncoding];

    NSLog(@"syncSocket trace 1"); [syncSocket writeData:data]; NSLog(@"syncSocket trace 2");

[ウィンドウ addSubview:viewController.view]; [ウィンドウ makeKeyAndVisible]; はいを返します。}

データを送信し続けることはなく、writeData は常にブロックされます。IP 192.168.0.30 は私の Mac の IP です。上記で提案したように、ポート12345を使用しました。

しかし、受信するために Mac で何をしなければならないのかよくわかりません??

ご覧のとおり、実際に syncsocket を使用すると、ブロックされます。

asyncSocket も試してみたところ、asyncsocket クラスで次のメッセージが表示されました: writeStream Can NOT Accept Bytes

Mac を正しくセットアップしていない可能性があります。つまり、テストするために Mac で実行する必要があるアプリは何ですか? 多くの感謝!

4

1 に答える 1

3

価値があるのは、これは具体的には、AsyncSocket を使用して一部のデータを読み取る一般的な方法です。

-(void)onSocket:(AsyncSocket *)sock
        didReadData:(NSData*)data withTag:(long)tag
    {
    [data getBytes:&getMe length:sizeof(CommProt)];
    // now, you must roll in the next read...
    [sock readDataToLength:sizeof(CommProt) withTimeout:-1 tag:0];  

    // CommProt is your communications protocol, so sizeof(CommProt)
    // is how much to read at a chunk.

    // you can now simply access the fields of getMe,
    // for example getMe.x, getMe.y, getMe.latestValue etc etc.

    // hope it helps!
    }

もちろん、最初の「プライマー」読み取りコマンドを以前にロールインしたことになります。

ホストに接続するときにそれを行うため、次のようになります。

-(void)onSocket:(AsyncSocket *)sock
        didConnectToHost:(NSString *)host port:(UInt16)port
    {
    if ( yourAppSaysItsOkToConnectAtThisMoment == NO )
        {
        [sock disconnect];  // (so easy, AsyncSockets is a masterpiece)
        return;
        }

    // .. blah blah

    // the critical 'primer' read command
    [sock readDataToLength:sizeof(CommProt) withTimeout:-1 tag:0];

    // .. blah blah
    }

(a) 最初に接続したときと (b) もちろん、各読み取りの後、2 つの場所で次の読み取りをロールインする必要があることを忘れないでください。

この例では、通信プロトコルは次のようになります...

typedef struct _CommProt        // v.3
    {
    BOOL        pressExplosionButton;
    BOOL        pressFireworksButton;
    float       usersSteering;
    float       usersTemperature;
    float       usersAltitude;
    float       usersAngle;
    }
    CommProt;

この例の「getMe」のような変数は、単純に次のようになります。

    CommProt                getMe;
    CommProt                sendMe;

このタイプの通信プロトコルを理解するのに苦労している場合は、次の長い回答も試してください。

タブレット(iPad/Android)-サーバー通信プロトコル

AsyncSocket は信じられないほど美しいです。これは謎めいた Justin Voss によって書かれました。彼はインターネットを世界に公開した後、それをやめたようです。これまでに作成されたライブラリの中で最高のものの 1 つであり、傑作です。

それが役に立てば幸い。

于 2011-03-18T12:38:58.457 に答える