AsyncUdpSocket как использовать получить - PullRequest
10 голосов
/ 18 ноября 2010

Я пытаюсь запустить на симуляторе программу для 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 ]

6 голосов
/ 10 мая 2011

Я новичок в 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 голос
/ 08 ноября 2012
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 голосов
/ 04 января 2017

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

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

[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

Надеюсь, это кому-нибудь пригодится.

0 голосов
/ 15 марта 2011

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

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

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

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

[listenSocket acceptOnPort:port error:&error]

Вот ссылка на пример кода .

...