10

我正在尝试让一个在模拟器上运行的 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 示例、教程、操作方法等,但我找不到示例。因此,如果有人想解释它或知道一个很好的解释,将不胜感激。

如果您不知道答案,无论如何感谢您的阅读!

4

4 回答 4

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 数据。我不是想侮辱你的智商,但过去我花了很长时间试图追踪网络代码错误,而问题实际上是我的网络配置。

于 2011-05-09T20:00:10.423 回答
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];
于 2012-11-08T09:04:26.607 回答
0

不确定这是否会有所帮助,但我遇到了同样的问题,这就是我解决它的方法。

就我而言,问题在于:

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

位于“错误”的地方。

如果你调用[self.socket receiveWithTimeout:-1 tag:0]; 在方法didFinishLaunchingWithOptions中,无论您做什么,套接字都不会工作(即使您尝试在新线程中启动它)。为了解决这个问题,我制作了一个按钮并将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

希望这对某人有帮助。

于 2017-01-04T00:21:28.937 回答
-2

我不熟悉这个库,但查看他们的 Google 代码项目中的示例代码会发现一些事情。

首先,我没有看到您描述的这个回调的任何提及。看起来你应该实现:

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

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

[listenSocket acceptOnPort:port error:&error]

这是示例代码的链接。

于 2011-03-15T11:49:06.677 回答