AsyncUdpSocket как использовать получение

Я пытаюсь получить программу для 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, учебники, как (и) и многое другое, но я просто не могу найти пример. Поэтому, если кто-то хотел бы объяснить это или знает сидеть с хорошим объяснением, это было бы очень признательно.

Если вы не знаете ответа, спасибо в любом случае за чтение!

Ответ 1

Я новичок в Objective C (так что несу с моим незнанием), но я смог получить AsyncUdpSocketDelegate для получения, по большей части. Несколько вещей, чтобы попробовать/подтвердить:

  • Убедитесь, что класс self, который вы инициализируете как делегат сокета, - это класс, на который вы ожидаете обратные вызовы.

  • Убедитесь, что ваш класс использует протокол AsyncUdpSocketDelegate. Я не уверен, что это действительно необходимо, но это не могло бы повредить. В заголовке вашего класса выглядит:

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

  • Убедитесь, что ваши методы делегата объявлены в вашем интерфейсе и. Подпись метода должна выглядеть так: - (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port;

  • Попробуйте вызвать receiveWithTimeout с ненулевым значением таймаута. Может дать вам разные результаты.

  • Используйте Wireshark, чтобы убедиться, что вы фактически получая данные UDP, когда и где вы думаете. я не пытаясь оскорбить ваш интеллект, но я потратил немало времени, пытаясь для отслеживания ошибок сетевого кода в прошлое, когда проблема была моя конфигурация сети.

Ответ 2

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];

Ответ 3

Не уверен, что это будет полезно, но у меня была такая же проблема, и вот как я ее исправил.

В моем случае проблема заключалась в следующем:

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

находился в "неправильном" месте.

Если вы вызываете [self.socket receiveWithTimeout: -1 tag: 0]; в методе didFinishLaunchingWithOptions, сокет не будет работать независимо от того, что вы делаете (даже если вы попытаетесь запустить его в новом потоке). Чтобы исправить эту проблему, я сделал кнопку и переместил вызов receiveWithTimeout на метод, который вызывается при нажатии кнопки. Я предполагаю, что ASyncUdpSocket не любит что-то о обработке потоков в didFinishLaunchingWithOptions.

Я разместил свой рабочий пример кода ниже (используя XCode 5.1.1). Это полный файл AppDelegate для моего проекта 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

Надеюсь, это кому-то поможет.

Ответ 4

Я не знаком с этой библиотекой, но, глядя на пример кода из своего проекта Google Code, вы узнаете несколько вещей.

Во-первых, я не вижу упоминания об этом обратном вызове, который вы описываете. Похоже, вы должны реализовать:

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

Также в примере сервер запускается со следующей строкой:

[listenSocket acceptOnPort:port error:&error]

Здесь ссылка на пример кода.