Techracho

iPhone用 超手抜きUDPサーバ

このエントリーをはてなブックマーク Share
2010.01.30    ネットワーク, 馬場   タグ: , , —    baba   

先日のiPhone性能検証で作ったソースの一部として、超手抜きUDPサーバのコードを載せておきます。
CFSocketが思ったよりも使いにくいので、BSDソケットほとんど生です・・・

/**
 * 手抜きUDPサーバ
 */
#import <netinet/in.h>
#import <Foundation/Foundation.h>

@interface MyUdpConnection : NSObject {
	id delegate;
}
- (id)initWithDelegate:(id)_delegate; //receiveData:(NSData*)data を実装すること
- (void)bind;
- (void)bindThread;
@end

/**
 * 手抜きUDPサーバ実装部
 */
@implementation MyUdpConnection

// 初期化
- (id)initWithDelegate:(id)_delegate {
	delegate = _delegate;
	return self;
}

// 受信開始
- (void)bind {
	NSThread *th = [[NSThread alloc]initWithTarget:self selector:@selector(bindThread) object:nil];
	[th start];
}

// 受信用スレッド
- (void)bindThread {
	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];

	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_port = htons(5555); //適当なポートで待機
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(INADDR_ANY);

	int sock = socket(AF_INET, SOCK_DGRAM, 0);
	bind(sock, (struct sockaddr *)&addr, sizeof(addr));

	char buf[100000]; //100KBまで対応
	while (1) {
		//ここでデータを受信するまでブロックされる
		int size = recv(sock, buf, sizeof(buf), 0);

		//NSDataに変換し、delegateに通知
		NSData *data = [NSData dataWithBytes:buf length:size];
		[delegate performSelectorOnMainThread:@selector(receiveData:) withObject:data waitUntilDone:YES];
	}

	[pool drain];
}
@end

これを使うと、たとえばViewControllerなどで

- (void)receiveData:(NSData *)data;

を実装しておいて、

MyUdpConnection *udp = [[MyUdpConnection alloc]initWithDelegate:self];
[udp bind];

のようにすれば、データを受信したときにreceiveData:が呼ばれます。

エラー処理や再送処理はおろか、ポート番号すらべた書きのものですが、重要でないデータを受け取る分には、ちょっと改良すれば使い物になりそうです。

COPYRIGHT [C] 2009 BEYOND PERSPECTIVE SOLUTIONS LTD. ALL RIGHTS RESERVED.