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]
Здесь ссылка на пример кода.