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を使って送受信するので、処理部が楽になっているはず。今回はここまで。