10

I am trying to get a program for iPhone running on the simulator. My problem is with receiving UDP data. I use asyncUdpSocket. If I make a socket and use sendData:(NSData) toHost:,... well it works fine.

The think i can just not figure out is how the receive functions works.

I assume something like this:

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

I believe it should then call the method -(BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long) fromHost:(NSString *)host port:(UInt16)port

Well i put a NSLog in that method and it is never called. Well [socket receive,..] is the only receive method so i guess it should be that one... or is there another method i have to use? Or do I have to make some additions to my delegate or whatever... I just can't figure out how i have to do it

I searched for asyncUdpSocket example(s), tutorials, how to('s) and more but I just can't find a example. So if anyone would like to explain it or knows a sit with a good explanation it would be very appreciated.

If you don't know the answer thanks anyway for reading!

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Saren Inden
  • 3,450
  • 4
  • 32
  • 45
  • 1
    you should change the tag "asyncsocket" to "asyncudpsocket" and add "cocoaasyncsocket" – lm2s Mar 18 '11 at 11:37
  • Have you already resolved this issue? If not tell me and I'll email you a simple Xcode project that uses Bonjour and AsyncUdpSocket to send a message from iOS (client) to Mac OS X (server). – lm2s Mar 18 '11 at 19:22
  • Im2s can you please email ME your project? my email is andreycdmd@gmail.com – Andrey Chernukha Jan 10 '12 at 16:45

4 Answers4

6

I'm new with Objective C (so bear with my ignorance of it), but I have been able to get AsyncUdpSocketDelegate to receive, for the most part. A few things to try/confirm:

  1. Make sure the self class that you are initializing as your socket delegate is the class that you're expecting the callbacks on.

  2. Make sure your class adopts the AsyncUdpSocketDelegate protocol. I'm not sure if this is actually necessary, but it couldn't hurt. In your class header, looks like:

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

  3. Make sure you have your delegate methods declared in your interface and implementation. The method signature should look like this: - (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port;

  4. Try calling receiveWithTimeout with a non-zero timeout value. May give you different results.

  5. Use Wireshark to make sure you are in fact receiving UDP data when and where you think you are. I'm not trying to insult your intelligence, but I've spent quite a while trying to track down network code bugs in the past when the issue was actually my network configuration.

Kongress
  • 2,244
  • 3
  • 20
  • 30
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];
ygweric
  • 1,002
  • 1
  • 7
  • 22
0

Not sure if this will be helpful, but I had the same problem, and here is how I fixed it.

In my case, the problem was that:

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

was located in the "wrong" place.

If you call [self.socket receiveWithTimeout:-1 tag:0]; in the method didFinishLaunchingWithOptions, the socket won't work regardless of what you do (even if you try launching it in a new thread). To fix this issue, I made a button and moved the receiveWithTimeout call to a method called when the button is clicked. My guess is that ASyncUdpSocket doesn't like something about the thread handling in didFinishLaunchingWithOptions.

I have posted my working sample code below (using XCode 5.1.1). These are the complete AppDelegate files for my Xcode project.

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

Hope this is helpful to someone.

Graham
  • 1
  • 1
-2

I'm not familiar with this library but looking at the sample code from their Google Code Project reveals a few things.

First of, I don't see any mention of this callback you describe. Looks like you're supposed to implement:

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

Also in the example the server is started with the following line:

[listenSocket acceptOnPort:port error:&error]

Here's a link to the sample code.

hjaltij
  • 885
  • 6
  • 8
  • 1
    You are refering to the AsyncSocket (TCP) version, not the AsyncUdpSocket (UDP) as the original question is about. – lm2s Mar 18 '11 at 11:36