0

我正在尝试在目标 C 中发送 UDP 数据包。更具体地说,使用针对 iphone 6.1 模拟器的 xcode 进行构建。

我似乎无法真正收到我发送的数据。奇怪的是,我确实收到了一个数据事件......数据刚刚被截断为长度 0。

我已经尽可能地减少它,做一个我认为应该通过的简单测试。

#import "UdpSocketTest.h"
#include <arpa/inet.h>
#import <CoreFoundation/CFSocket.h>
#include <sys/socket.h>
#include <netinet/in.h>

@implementation UdpSocketTest

static int receivedByteCount = 0;
void onReceive(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info);
void onReceive(CFSocketRef socket, CFSocketCallBackType type, CFDataRef address, const void *data, void *info) {
    // this gets called once, but CFDataGetLength(data) == 0
    receivedByteCount += CFDataGetLength(data);
}

-(void) testUdpSocket {
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_len = sizeof(addr);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(5000); // <-- doesn't really matter, not sending from receiver
    inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
    CFSocketContext socketContext = { 0, (__bridge void*)self, CFRetain, CFRelease, NULL };

    // prepare receiver
    CFSocketRef receiver = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_DGRAM, IPPROTO_UDP ,kCFSocketDataCallBack, (CFSocketCallBack)onReceive, &socketContext);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(NULL, receiver, 0), kCFRunLoopCommonModes);
    CFSocketConnectToAddress(receiver, CFDataCreate(NULL, (unsigned char *)&addr, sizeof(addr)), -1);

    // point sender at receiver
    CFSocketRef sender = CFSocketCreate(kCFAllocatorDefault, PF_INET, SOCK_DGRAM, IPPROTO_UDP, kCFSocketDataCallBack, (CFSocketCallBack)onReceive, &socketContext);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), CFSocketCreateRunLoopSource(NULL, sender, 0), kCFRunLoopCommonModes);
    CFSocketConnectToAddress(sender, CFSocketCopyAddress(receiver), -1);

    // send data of sixty zeroes, allow processing to occur
    CFSocketSendData(sender, NULL, (__bridge CFDataRef)[NSMutableData dataWithLength:60], 2.0);
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];

    // did the data arrive?
    STAssertTrue(receivedByteCount > 0, @"");
    // nope
}
@end

我究竟做错了什么?我知道这很明显,但我看不到。

4

1 回答 1

2

我很惊讶你收到任何回调——你从来没有真正将你的接收器绑定到你的本地端口。您正在创建两个套接字并告诉他们“我去发送数据到127.0.0.1:5000”,但是您没有说“我想在127.0.0.1:5000.

为此,您应该调用CFSocketSetAddress接收器套接字,而不是 CFSocketConnectToAddress. 这相当于bind(2)在底层原生 BSD 套接字上调用系统调用。

于 2013-04-05T04:32:59.970 回答