2012-02-10 12 views
5

この件に関するいくつかのGoogle検索といくつかの読書を行ってきましたが、検索にどれくらいの時間を費やしてもそれを正しく得ることはできませんでした。IOSのCFSocketを使ったUDPブロードキャスト

私がしたいことは、自分のネットワークに接続されているデバイスのブロードキャストメッセージを、自分が提供するサービスに興味を持って広告することです。 wiresharkを使用して私は私のネットワーク上で送信されたが、自分のサービスの興味のための私のブロードキャスト検索ではなく、送信したいネットワークデバイスからのブロードキャスト/通知メッセージを見ることができます。 しかし、ネットワークユーティリティでは、ソケットが作成されているのを見ることができますが、リッスンしているか接続しているかはわかりません。

はい私はこれを行うために使用できるライブラリがあることを知っていますが、私は自分自身で何かを構築したいと思っています。

MySocket.h

#import <Foundation/Foundation.h> 
#import <CoreFoundation/CoreFoundation.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#if TARGET_OS_IPHONE 
#import <CFNetwork/CFNetwork.h> 
#endif 

@interface MySocket : NSObject 
{ 
    NSString* _message; 
    CFSocketRef cfSocket; 
    CFRunLoopSourceRef cfSource; 

} 

- (void)listen; 
@end 

MySocket.m

#import "MySocket.h" 

#define MAX_UDP_DATAGRAM_SIZE 65507 

@implementation MySocket 


static void socketCallback(CFSocketRef cfSocket, CFSocketCallBackType 
          type, CFDataRef address, const void *data, void *userInfo) 
{ 
    NSLog(@"socketCAllBAck was called"); 
}  

- (void)listen 
{ 
    //Enable broadcast to network hosts   
    int yes = 1; 
    int setSockResult = 0; 
    _message = [[NSMutableString alloc ] initWithString: @"M-SEARCH *HTTP/1.1\r\nHOST:239.255.255.250:1900\r\nMAN:\"ssdp:discover\"\r\nST:ssdp:all\r\nMX:1\r\n\r\n"]; 

    CFSocketContext socketContext = {0, self, NULL, NULL, NULL}; 

    /* Create the server socket as a UDP IPv4 socket and set a callback */ 
    /* for calls to the socket's lower-level accept() function */ 
    cfSocket = CFSocketCreate(NULL, PF_INET, SOCK_DGRAM, IPPROTO_UDP, 
           kCFSocketAcceptCallBack | kCFSocketDataCallBack , (CFSocketCallBack)socketCallback, &socketContext); 
    if (cfSocket == NULL) 
     NSLog(@"UDP socket could not be created\n"); 

    /* Re-use local addresses, if they're still in TIME_WAIT */ 
    setSockResult = setsockopt(CFSocketGetNative(cfSocket), SOL_SOCKET, SO_BROADCAST, (void *)&yes, sizeof(yes)); 

    if(setSockResult < 0) 
     NSLog(@"Could not setsockopt for broabcast"); 

    /* Set the port and address we want to listen on */ 
    struct sockaddr_in addr; 
    memset(&addr, 0, sizeof(addr)); 
    addr.sin_len = sizeof(addr); 
    addr.sin_family = AF_INET; 
    addr.sin_addr.s_addr = inet_addr("239.255.255.250"); 
    //inet_pton(AF_INET, "239.255.255.250", &(addr.sin_addr)); 

    addr.sin_port = htons(1900); 
    //addr.sin_addr.s_addr = htonl(INADDR_ANY); 

    NSData *address = [ NSData dataWithBytes: &addr length: sizeof(addr) ]; 
    if (address != nil && CFSocketSetAddress(cfSocket, (CFDataRef) address) != kCFSocketSuccess) { 
     NSLog(@"CFSocketSetAddress() failed\n"); 
     CFRelease(cfSocket); 
    }  

    CFDataRef data = CFDataCreate(NULL, (const UInt8*)[_message UTF8String], [_message lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); 

    setSockResult = CFSocketSendData(cfSocket, (CFDataRef)address, data, 0.0); 
    if(kCFSocketSuccess != setSockResult) NSLog(@"Unable to send data, %i", setSockResult); 
    else NSLog(@"Sending data"); 

    cfSource = CFSocketCreateRunLoopSource(kCFAllocatorDefault, cfSocket, 0); 

    if(cfSource == NULL) 
     NSLog(@"CFRunLoopSourceRef is null"); 

    CFRunLoopAddSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode); 

    NSLog(@"Socket listening on port 1900"); 

     CFRelease(cfSource); 
    CFRelease(cfSocket); 
    [address release]; 
    data = nil; 
    CFRunLoopRun(); 
} 

- (void)dealloc 
{ 
    CFRunLoopRemoveSource(CFRunLoopGetCurrent(), cfSource, kCFRunLoopDefaultMode); 
    CFRelease(cfSource); 
    CFRelease(cfSocket); 
    [_message release]; 
    [super dealloc]; 
} 

@end 

編集:すべてがデータを送信するためにコールされるまでうまく動作します。

これは私が行方不明に動作するためには、何か小さいが重要ですか? または私は大きな画像が欠けていますか?

ご迷惑をおかけして申し訳ございません。事前に 感謝とアドレス

CFDataRef address=CFDataCreate(kCFAllocatorDefault,(UInt8 *)&addr,sizeof(addr)); 

答えて

0

使い方については、この初期の素敵な週末を持っています。私は今これをテストしました。

1

でSetAdressを削除し、すべての作業罰金となります

関連する問題