AsyncUdpSocket如何使用receive

时间:2010-11-18 13:18:25

标签: iphone cocoa-touch udp asyncsocket

我正在尝试在模拟器上运行iPhone程序。我的问题是接收UDP数据。我使用asyncUdpSocket。如果我创建一个套接字并使用sendData:(NSData) toHost:,那么它可以正常工作。

我无法弄清楚接收功能是如何工作的。

我假设这样的事情:

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

我相信它应该调用方法-(BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long) fromHost:(NSString *)host port:(UInt16)port

我在该方法中放置了一个NSLog,它永远不会被调用。那么[socket receive,..]是唯一的接收方法,所以我想它应该是那个...或者是否还有另一种方法我必须使用?或者我是否需要为我的代表或其他任何内容添加一些内容......我无法弄清楚我必须如何做到这一点

我搜索了asyncUdpSocket示例,教程,如何('s)等等,但我找不到一个例子。因此,如果有人想解释它或知道一个好的解释,那将非常感激。

如果您不知道答案,那么无论如何都要阅读!

4 个答案:

答案 0 :(得分:6)

我是Objective C的新手(所以请不要理解它),但我能够在大多数情况下让AsyncUdpSocketDelegate接收。一些事情要尝试/确认:

  1. 确保您正在初始化为套接字委托的self类是您期望回调的类。

  2. 确保您的班级采用AsyncUdpSocketDelegate协议。我不确定这是否真的有必要,但它不会受到伤害。在您的类标题中,看起来像:

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

  3. 确保在接口和实现中声明了委托方法。方法签名应如下所示: - (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port;

  4. 尝试使用非零超时值调用receiveWithTimeout。可能会给你不同的结果。

  5. 使用Wireshark确保您拥有 实际上当和时接收UDP数据 你认为你在哪里。我不是 试图侮辱你的智慧, 但我花了很长时间尝试 跟踪网络代码中的错误 实际问题的过去 我的网络配置。

答案 1 :(得分: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];

答案 2 :(得分:0)

不确定这是否有用,但我遇到了同样的问题,这就是我修复它的方法。

就我而言,问题在于:

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

位于“错误”的地方。

如果你在方法 didFinishLaunchingWithOptions [self.socket receiveWithTimeout:-1 tag:0]; >,无论你做什么,套接字都不会工作(即使你尝试在新线程中启动它)。为解决此问题,我创建了一个按钮并将 receiveWithTimeout 调用移动到单击按钮时调用的方法。我的猜测是ASyncUdpSocket不喜欢 didFinishLaunchingWithOptions 中的线程处理。

我已在下面发布了我的工作示例代码(使用XCode 5.1.1)。这些是我的Xcode项目的完整AppDelegate文件。

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

希望这对某人有帮助。

答案 3 :(得分:-2)

我不熟悉这个库,但查看Google代码项目中的示例代码可以看出一些事情。

首先,我没有看到你描述过的回调。看起来你应该实施:

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

此外,在示例中,服务器使用以下行启动:

[listenSocket acceptOnPort:port error:&error]

这是sample code的链接。