iPhone/iPadネットワークプログラミング(8)〜IPアドレス指定して接続〜

久しぶりにネットワークプログラミングの話。今回はIPベースでやり取りする方法について。
まぁ、サーバのIPが分かっている場合に使えるかな。


てなわけで、サーバから。
ソケットを用意して、接続を待つ。まずは、ソケット作成から。
ソケット作成には NSSocketPort を使うと楽だ。ただしMac専用。iPhoneをサーバにする場合は、別の方法(以前書いた)でソケットを準備する。今回は、NSSocketPortを使う。

NSSocketPort* socketPort = [[NSSocketPort alloc] initWithTCPPort:7000];
if(socketPort){
    NSFileHandle* socketHandle = [[NSFileHandle alloc] initWithFileDescriptor:[socketPort socket]
                                                               closeOnDealloc:YES];
    if(socketHandle){
        [[NSNotificationCenter defaultCenter] addObserver:self 
                                                 selector:@selector(acceptConnect:)
                                                     name:NSFileHandleConnectionAcceptedNotification
                                                    object:socketHandle];
        [socketHandle acceptConnectionInBackgroundAndNotify];
    }else{
        NSLog(@"socket handle error");
   }
}else{
    NSLog(@"socket port error");
}

サーバ側はポートを用意すればOK。あとは、これまでと同じように、NotificationCenterに登録して、接続を待てば良い。
接続時とデータ受信時は以下のようにすればOK。

NSFileHandle* readHandle;

- (void) acceptConnect:(NSNotification*)notification
{
   readHandle = [[[n userInfo] objectForKey:NSFileHandleNotificationFileHandleItem] retain];
   [[NSNotificationCenter defaultCenter] addObserver:self 
                                            selector:@selector(readData:)
                                                name:NSFileHandleDataAvailableNotification
                                              object:readHandle];
   [readHandle waitForDataInBackgroundAndNotify];
}

- (void) readData:(NSNotification*)notification
{
   NSData* d = [readHandle availableData];
   if([d bytes] > 0){
      NSString *str = [[NSString alloc] initWithData:d encoding:NSUTF8StringEncoding];
      NSLog(@"%@", [NSString stringWithFormat:@"送られてきた文字列:%@", str]);
      [readHandle waitForDataInBackgroundAndNotify];
   }else{
      NSLog(@"切れました");
   }
}

最後に、後始末

- (void) dealloc
{
   [[NSNotificationCenter defaultCenter] removeObserver:self];
   [readHandle release];
   [super dealloc];
}

サーバ側は以上。


次は、クライアント側。サーバのIPを192.168.11.1として話をすすめる。
まず接続する。

NSFileHandle* streamHandle;

NSString* ipAddressString = @"192.168.11.1";
struct sockaddr_in serverAddr;
memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_port = htons(7000);     //サーバ側の待ち受けポート7000
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr([ipAddressString cStringUsingEncoding:NSASCIIStringEncoding]);
int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
	
connect(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr));  //接続要求
	
streamHandle = [[NSFileHandle alloc] initWithFileDescriptor:serverSocket closeOnDealloc:YES];
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(readData:)
                                             name:NSFileHandleDataAvailableNotification
                                            object:streamHandle];
[streamHandle waitForDataInBackgroundAndNotify];

今回は、C言語の socketとconnectを使って、接続している。クライアント側もNSFileHandleを使う。
データの送受信は streamHandle を使ってやればOK。受信は availableData を使って、送信は writeData を使う。
あとは後始末。

- (void) dealloc
{
   [[NSNotificationCenter defaultCenter] removeObserver:self];
   [streamHandle release];
   [super dealloc];
}


今回は、全部 NSFileHandleを使って送受信するので、処理部が楽になっているはず。今回はここまで。