2010-11-18 7 views
10

Sto cercando di ottenere un programma per iPhone in esecuzione sul simulatore. Il mio problema è con la ricezione di dati UDP. Io uso asyncUdpSocket. Se creo un socket e utilizzo sendData:(NSData) toHost:, ... beh funziona correttamente.AsyncUdpSocket come utilizzare ricevere

Il solo pensiero che non riesco a capire è come funzionano le funzioni di ricezione.

presumo qualcosa di simile:

socket = [[AsyncUdpSocket alloc] initWithDelegate:self]; 
[socket bindToPort:8000] error:nil] //returns YES 
[socket receiveWithTimeout:-1 tag:1]; 

credo che dovrebbe quindi chiamare il metodo -(BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long) fromHost:(NSString *)host port:(UInt16)port

Beh ho messo un NSLog in che modo e non è mai chiamato. Bene [socket receive, ..] è l'unico metodo di ricezione quindi suppongo che dovrebbe essere quello ... o c'è un altro metodo che devo usare? O devo fare alcune aggiunte al mio delegato o qualsiasi altra cosa ... Non riesco a capire come devo farlo

Ho cercato per esempio (s) asyncUdpSocket, tutorial, come (s) e altro ancora, ma non riesco a trovare un esempio. Quindi, se qualcuno vorrebbe spiegarlo o conosce una seduta con una buona spiegazione, sarebbe molto apprezzato.

Se non si conosce la risposta grazie comunque per la lettura!

+1

dovresti cambiare il tag "asyncsocket" in "asyncudpsocket" e aggiungere "cocoaasyncsocket" – lm2s

+0

Hai già risolto questo problema? In caso contrario, mi verrà inviato un semplice progetto Xcode che utilizza Bonjour e AsyncUdpSocket per inviare un messaggio da iOS (client) a Mac OS X (server). – lm2s

+0

Im2s puoi inviare per email ME al tuo progetto? la mia email è [email protected] –

risposta

6

Sono nuovo con l'Objective C (quindi sopporto la mia ignoranza), ma sono stato in grado di ottenere AsyncUdpSocketDelegate per ricevere, per la maggior parte. Un paio di cose da provare/confermare:

  1. Assicurarsi che la classe self che si inizializza come presa delegato è la classe che ci si aspetta i callback su.

  2. Assicurarsi che la classe adotti il ​​protocollo AsyncUdpSocketDelegate. Non sono sicuro che sia effettivamente necessario, ma non potrebbe ferire. Nella tua intestazione di classe, si presenta come:

    @interface |your class| : |super class| <|Other protocol(s)|, AsyncUdpSocketDelegate> {

  3. Accertarsi che siano presenti i tuoi metodi delegato dichiarati nell'interfaccia e implementazione. La firma del metodo dovrebbe essere simile a questa: - (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port;

  4. Provare a chiamare receiveWithTimeout con un valore di timeout diverso da zero. Può darti risultati diversi.

  5. Utilizzare Wireshark per assicurarsi che si sia infatti a ricevere i dati UDP quando e dove si pensa di essere.Io non sono cercando di insultare la tua intelligenza, ma ho passato un po 'di tempo cercando per rintracciare i bug del codice di rete nel quando il problema era in realtà la mia configurazione di rete.

+2

se si sta adottando un protocollo formale non è necessario dichiarare i propri metodi nell'interfaccia. questo è il significato del protocollo. –

+1

+1 per lo scaricamento dei cavi, mi ha salvato così tante volte. –

+0

@Grady Corretto la parte relativa alla dichiarazione dell'interfaccia in base al commento. – Kongress

-2

Non ho familiarità con questa libreria, ma guardando il codice di esempio dal loro Progetto Google Code rivela alcune cose.

Prima di tutto, non vedo alcuna menzione di questa richiamata che descrivi. Sembra che si suppone di implementare:

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag 

Anche nell'esempio il server viene avviato con la seguente riga:

[listenSocket acceptOnPort:port error:&error] 

Ecco un link al sample code.

+1

Si sta facendo riferimento alla versione AsyncSocket (TCP), non all'AsyncUdpSocket (UDP) come la domanda originale riguarda. – lm2s

+0

Ah, mi dispiace. – hjaltij

1
AsyncUdpSocket *socket=[[AsyncUdpSocket alloc]initWithDelegate:self];  
//receiveWithTimeout is necessary or you won't receive anything 
[socket receiveWithTimeout:-1 tag:2]; //-------here 
NSData *data=[@"Hello from iPhone" dataUsingEncoding:NSUTF8StringEncoding]; 
[socket sendData:data toHost:bchost port:9003 withTimeout:-1 tag:1]; 
+0

Ho bisogno della demo ... plzz – AKSH

0

Non sono sicuro se questo sarà utile, ma ho avuto lo stesso problema, ed ecco come ho riparato.

Nel mio caso, il problema è che:

[self.socket receiveWithTimeout:-1 tag:0]; 

si trovava nel posto "sbagliato".

Se si chiama [self.socket receiveWithTimeout: -1 tag: 0]; nel metodo didFinishLaunchingWithOptions, il socket non funzionerà indipendentemente da ciò che si fa (anche se si prova a lanciarlo in una nuova discussione). Per risolvere questo problema, ho creato un pulsante e spostato la chiamata receiveWithTimeout a un metodo chiamato quando si fa clic sul pulsante. La mia ipotesi è che ASyncUdpSocket non sia interessato alla gestione dei thread in didFinishLaunchingWithOptions.

Ho pubblicato il mio codice di esempio di lavoro (utilizzando XCode 5.1.1). Questi sono i file AppDelegate completi per il mio progetto Xcode.

AppDelegate.h

#import <UIKit/UIKit.h> 
#import "AsyncUdpSocket.h" 

@interface AppDelegate : UIResponder <UIApplicationDelegate, AsyncUdpSocketDelegate> 

@property (strong, nonatomic) UIWindow *window; 
@property (strong, nonatomic) AsyncUdpSocket *udpSocket; 
@property (strong, nonatomic) UILabel *receiver; 

@end 

AppDelegate.m

#import "AppDelegate.h" 
#import "AsyncUdpSocket.h" 
#import <UIKit/UIKit.h> 
#import <CFNetwork/CFNetwork.h> 

@implementation AppDelegate 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    // Create the main window 
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    self.window.backgroundColor = [UIColor whiteColor]; 
    [self.window makeKeyAndVisible]; 

    // Create a label for showing received text 
    self.receiver = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 80.0)]; 
    self.receiver.text = @"No message, yet!"; 
    self.receiver.textColor  = [UIColor blackColor]; 
    [self.window addSubview:self.receiver]; 

    // Create a button for sending messages 
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; 
    [button setFrame:CGRectMake(80.0, 210.0, 160.0, 40.0)]; 
    [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside]; 
    [button setTitle:@"Start Game" forState:UIControlStateNormal]; 
    [button setBackgroundColor:[UIColor blueColor]]; 
    [self.window addSubview:button]; 

    @try { 
     self.udpSocket = [[AsyncUdpSocket alloc] initWithDelegate:self]; 
     if (![self.serverSocket bindToPort:9003 error:nil]) { 
      NSLog(@"COULD NOT BIND TO PORT"); 
     } 
     if (![self.udpSocket enableBroadcast:YES error:nil]) { 
      NSLog(@"COULD NOT ENABLE BROADCASTING"); 
     } 
    } @catch (NSException * e) { 
     NSLog(@"Exception: %@", e); 
    } 
    return YES; 
} 

- (void)buttonClick:(UIButton*)button { 
    NSData * data = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding]; 
    [self.udpSocket receiveWithTimeout:-1 tag:0]; 
    if (![self.udpSocket sendData:data toHost:@"127.0.0.1" port:9003 withTimeout:0.2 tag:1]) { 
     NSLog(@"COULD NOT SEND DATA"); 
    } else { 
     NSLog(@"Sent packet (from %@:%d to 127.0.0.1:9001)", self.udpSocket.localHost, self.udpSocket.localPort); 
    } 
} 

- (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port { 
    NSLog(@" Received data (from %@:%d) - %@", host, port, data); 
    self.receiver.text = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; 
    [self.udpSocket receiveWithTimeout:-1 tag:0]; 

    return YES; 
} 

@end 

Spero che questo è utile a qualcuno.