2010-11-18 29 views
10

Tôi đang cố gắng để có được một chương trình cho iPhone chạy trên giả lập. Vấn đề của tôi là nhận dữ liệu UDP. Tôi sử dụng asyncUdpSocket. Nếu tôi tạo một ổ cắm và sử dụng sendData:(NSData) toHost:, ... nó hoạt động tốt.AsyncUdpSocket làm thế nào để sử dụng nhận được

Nghĩ rằng tôi không thể hiểu được cách thức hoạt động của chức năng nhận.

tôi giả sử một cái gì đó như thế này:

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

Tôi tin rằng nó nên sau đó gọi phương thức -(BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long) fromHost:(NSString *)host port:(UInt16)port

Vâng tôi đặt một NSLog trong phương pháp đó và nó không bao giờ gọi. Vâng [socket receive, ..] là phương thức nhận duy nhất vì vậy tôi đoán nó nên là một ... hoặc là có một phương pháp tôi phải sử dụng? Hoặc tôi có phải thực hiện một số bổ sung cho đại biểu của tôi hoặc bất cứ điều gì ... Tôi chỉ không thể tìm ra cách tôi phải làm điều đó

Tôi đã tìm kiếm ví dụ asyncUdpSocket, hướng dẫn, cách ('s) và nhiều hơn nữa nhưng tôi không thể tìm thấy một ví dụ. Vì vậy, nếu bất cứ ai muốn giải thích nó hoặc biết một ngồi với một lời giải thích tốt nó sẽ rất đánh giá cao.

Nếu bạn vẫn chưa biết câu trả lời, hãy đọc!

+1

bạn nên thay đổi thẻ "asyncsocket" thành "asyncudpsocket" và thêm "cocoaasyncsocket" – lm2s

+0

Bạn đã giải quyết vấn đề này chưa? Nếu không cho tôi biết và tôi sẽ gửi email cho bạn một dự án Xcode đơn giản sử dụng Bonjour và AsyncUdpSocket để gửi thư từ iOS (máy khách) tới Mac OS X (máy chủ). – lm2s

+0

Im2s bạn có thể vui lòng gửi email cho ME dự án của bạn? email của tôi là [email protected] –

Trả lời

6

Tôi mới với Mục tiêu C (vì vậy hãy chịu sự thiếu hiểu biết của tôi về nó), nhưng tôi đã có thể nhận được AsyncUdpSocketDelegate để nhận được phần lớn. Một vài điều cần thử/xác nhận:

  1. Đảm bảo rằng lớp self mà bạn đang khởi tạo làm đại diện ổ cắm là lớp bạn đang mong đợi cuộc gọi lại.

  2. Đảm bảo lớp học của bạn sử dụng giao thức AsyncUdpSocketDelegate. Tôi không chắc liệu điều này có thực sự cần thiết hay không, nhưng nó không thể làm tổn thương. Trong phần đầu lớp học của bạn, trông giống như:

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

  3. Hãy chắc chắn rằng bạn có phương pháp đại biểu của bạn khai báo trong giao diện của bạn và thực hiện. Chữ ký phương thức sẽ trông giống như sau: - (BOOL)onUdpSocket:(AsyncUdpSocket *)sock didReceiveData:(NSData *)data withTag:(long)tag fromHost:(NSString *)host port:(UInt16)port;

  4. Hãy thử gọi receiveWithTimeout với giá trị thời gian chờ khác 0. Có thể cung cấp cho bạn kết quả khác nhau.

  5. Sử dụng Wireshark để đảm bảo bạn đang trong thực tế nhận dữ liệu UDP khi và nơi bạn nghĩ bạn đang ở.Tôi không phải là cố gắng xúc phạm trí thông minh của bạn, nhưng tôi đã dành một chút thời gian để thử để theo dõi lỗi mã mạng trong quá khứ khi vấn đề thực sự là cấu hình mạng của tôi.

+2

nếu bạn đang áp dụng giao thức chính thức, bạn không cần khai báo các phương thức của mình trong giao diện. đó là giao thức của cái gì. –

+1

+1 cho Wireshark, nó đã cứu tôi rất nhiều lần. –

+0

@Grady Đã sửa phần về khai báo giao diện dựa trên nhận xét của bạn. – Kongress

-2

Tôi không quen thuộc với thư viện này nhưng nhìn vào mã mẫu từ Dự án Google Code của họ cho thấy một vài điều.

Trước hết, tôi không thấy bất kỳ đề cập nào về cuộc gọi lại này mà bạn mô tả. Dường như bạn đang phải thực hiện:

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

Cũng trong ví dụ máy chủ được bắt đầu với dòng sau:

[listenSocket acceptOnPort:port error:&error] 

Dưới đây là một liên kết đến sample code.

+1

Bạn đang tham khảo phiên bản AsyncSocket (TCP), không phải là AsyncUdpSocket (UDP) như câu hỏi ban đầu. – lm2s

+0

Ahh, tôi xin lỗi. – hjaltij

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

Tôi cần bản trình diễn ... plzz – AKSH

0

Không chắc nếu điều này sẽ rất hữu ích, nhưng tôi đã có cùng một vấn đề, và đây là cách tôi cố định nó.

Trong trường hợp của tôi, vấn đề là:

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

nằm ở vị trí "sai".

Nếu bạn gọi [self.socket receiveWithTimeout: -1 tag: 0]; trong phương pháp didFinishLaunchingWithOptions, ổ cắm sẽ không hoạt động bất kể bạn làm gì (ngay cả khi bạn thử khởi chạy nó trong một chuỗi mới). Để khắc phục sự cố này, tôi đã thực hiện một nút và chuyển cuộc gọi receiveWithTimeout đến phương thức được gọi khi nút được nhấp. Tôi đoán là ASyncUdpSocket không thích điều gì đó về xử lý chuỗi trong didFinishLaunchingWithOptions.

Tôi đã đăng mã mẫu làm việc của mình bên dưới (sử dụng XCode 5.1.1). Đây là các tệp AppDelegate hoàn chỉnh cho dự án Xcode của tôi.

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 

Hy vọng điều này là hữu ích cho một ai đó.

Các vấn đề liên quan