グランドセントラルディスパッチをbsdソケットと組み合わせて使用して、icmp pingを送信しようとしています。DISPATCH_SOURCE_TYPE_WRITE と DISPATCH_SOURCE_TYPE_READ をディスパッチ ソースとして追加し、非同期で読み書きします。
これは、bsd ソケットを作成してディスパッチ ソースをインストールする方法です。
- (void)start
{
int err;
const struct sockaddr * addrPtr;
assert(self.hostAddress != nil);
// Open the socket.
addrPtr = (const struct sockaddr *) [self.hostAddress bytes];
fd = -1;
err = 0;
switch (addrPtr->sa_family) {
case AF_INET: {
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
if (fd < 0) {
err = errno;
}
} break;
case AF_INET6:
assert(NO);
// fall through
default: {
err = EPROTONOSUPPORT;
} break;
}
if (err != 0) {
[self didFailWithError:[NSError errorWithDomain:NSPOSIXErrorDomain code:err userInfo:nil]];
} else {
dispatch_source_t writeSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, fd, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_source_set_event_handler(writeSource, ^{
abort(); // testing
// call call method here to send a ping
});
dispatch_resume(writeSource);
//NSLog(@"testout");
dispatch_source_t readSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, fd, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
dispatch_source_set_event_handler(readSource, ^{
unsigned long bytesAvail = dispatch_source_get_data(readSource);
NSLog(@"bytes available: %lu", bytesAvail);
});
dispatch_resume(readSource);
}
}
//NSLog(@"testout");? が表示されます。面白いことに、書き込みブロックは //NSLog(@"testout"); の場合にのみ呼び出されます。コメントアウトされていません。これは非常に奇妙です。読み取りコールバックはテストしていません。送信は最初に機能する必要があります。
それで、ここで何が起こっているのですか?