5

クライアントに udp メッセージ (ブロードキャスト) を送信して応答が得られるという問題がありますが、これが 2 回表示されます。PC と UDP リスナーとの通信を確認すると、メッセージが 1 つしかありません。

おそらく、誰かがこれを解決する方法を教えてくれます。

メッセージの送信を開始するボタンを使用しています。

#import "ViewController.h"
#import "GCDAsyncUdpSocket.h"

@interface ViewController ()
{
    long tag;
    GCDAsyncUdpSocket *udpSocket;

}

@end

@implementation ViewController

- (void)setupSocket
{   udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];

    NSError *error = nil;

    if (![udpSocket bindToPort:1000 error:&error])
    {
        NSLog(@"Error binding: %@", error);
        return;
    }
    if (![udpSocket beginReceiving:&error])
    {
        NSLog(@"Error receiving: %@", error);
        return;
    }

    [udpSocket enableBroadcast:YES error: &error];

    NSLog(@"Ready");
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    if (udpSocket == nil)
    {
        [self setupSocket];
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)send:(id)sender{
    NSString *host = @"192.168.2.255";
    if ([host length] == 0)
    {
        NSLog(@"Address required");
        return;
    }

    NSLog(@"%@",host);

    int port = 8888;

    NSString *msg = @"1,0,1,2";

    NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
    [udpSocket sendData:data toHost:host port:port withTimeout:-1 tag:tag];

    NSLog(@"SENT (%i): %@", (int)tag, msg);

    tag++;

}

- (void)udpSocket:(GCDAsyncUdpSocket *)sock didReceiveData:(NSData *)data
        fromAddress:(NSData *)address
        withFilterContext:(id)filterContext
{
    NSString *msg = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    if (msg)
    {
        NSLog(@"RECV: %@", msg);
        tag++;
        NSLog(@"%li",tag);
    }
    else
    {
        NSString *host = nil;
        uint16_t port = 0;
        [GCDAsyncUdpSocket getHost:&host port:&port fromAddress:address];

        NSLog(@"RECV: Unknown message from: %@:%hu", host, port);
    }
}

@end

これが出力です!

2013-09-11 09:49:00.132 udptest[5145:907] 15
2013-09-11 09:49:08.218 udptest[5145:907] 192.168.2.255
2013-09-11 09:49:08.220 udptest[5145:907] SENT (15): 1,0,1,2
2013-09-11 09:49:08.319 udptest[5145:907] RECV: 0,0,0,0,0,0,0,0
2013-09-11 09:49:08.321 udptest[5145:907] 17
2013-09-11 09:49:08.323 udptest[5145:907] RECV: 0,0,0,0,0,0,0,0
2013-09-11 09:49:08.324 udptest[5145:907] 18

誰かが私を助けてくれたら、とても感謝しています。

4

2 に答える 2

13

「送信者」は 1 つのブロードキャスト UDP メッセージを送信し、「受信者」は 2 つのメッセージを受け取ります。

私はできる限り調査しましたが、これらは私の発見です:

1) Wireshark は UDP メッセージを 1 つだけ取得します。

2) udpSocket:didReceiveData:fromAddress:withFilterContext: 2 回発生します!

3) [GCDAsyncUdpSocket getHost:port:fromAddress:] で「アドレス」パラメーターを解析すると、ホスト = ::ffff:192.168.1.118が最初の時間、ホスト = 192.168.1.118が 2 番目の時間になります。

何らかの形でお役に立てば幸いです...

編集(可能な解決策を含む)

FIRST アドレス (ポイント 2 と 3 を参照) は、実際の IPv6 アドレスです。したがって、udpSocket:didReceiveData:... は、最初の送信者が IPv6アドレスであり、 2 回目の送信者が同じアドレスの IPv4アドレスであるため、2 回起動されると思います。

したがって、私の解決策は、UDP ソケットで IPv4 のみを有効にすることです。

[udpSocket setIPv4Enabled:YES];
[udpSocket setIPv6Enabled:NO];
于 2013-10-03T09:00:51.663 に答える
0

応答メッセージと要求メッセージの内容は同じですか。はいの場合、ここにあなたが遭遇している可能性のある 1 つのシナリオがあります。最初のパケットは、自分自身のために聞いているブロードキャストであり、2 番目のパケットは応答である可能性があります。より正確には、ブロードキャスト (pkt p1) を送信すると、送信者も p1 のコピーを取得できます。次に、受信者が応答 (pkt p2) を送信すると、応答も表示されます。

では、どうやって検証しよう。送信者のアドレス (UDP にはオプションがあります) を見て、それが自分のアドレスか他のホストのアドレスかを確認できます。

于 2013-09-11T16:01:59.067 に答える