gpt4 book ai didi

ios - 使用具有特定 IP 地址的 UDP

转载 作者:行者123 更新时间:2023-11-29 02:25:25 24 4
gpt4 key购买 nike

我正在尝试编写一个使用 UDP 与设备通信的 iOS 应用程序。该设备的文档表明它在特定 IP 地址 224.4.0.1 和特定端口号上进行通信。

我很难找出在特定 IP 地址上发送和接收 UDP 数据包的正确方法。这可能吗?

我写了一些测试代码,可以从一台 iOS 设备发送 UDP 数据包并在另一台设备上监听它。只要我将发送 IP 地址指定为 INADDR_BROADCAST 并将接收地址指定为 INADDR_ANY,我编写的代码就可以工作。一旦我将其中一个或两个更改为 224.4.0.1 地址,它就不再有效(发送方不报告任何错误,但接收方永远不会收到数据包)。

我的理解是224.4.0.1在为多播保留的IP地址范围内。我确保在绑定(bind)之前在监听套接字上设置 SO_REUSEADDR 选项。

我尝试最终使用的设备在我的网络上,但到目前为止还没有响应我尝试发送的任何内容。在我担心设备的具体细节之前,我想让我的测试用例适用于两部 iPhone。

我直接使用 Berkeley 套接字和/或使用 CFSocket 包装它们。我已经在早期项目中成功地将这些接口(interface)与 TCP 结合使用,因此我对它们的总体工作方式非常满意。

这是设置发送套接字的代码:

    struct sockaddr_in sin_send;
memset(&sin_send, 0, sizeof(sin_send));
sin_send.sin_len = sizeof(sin_send);
sin_send.sin_family = AF_INET;
sin_send.sin_port = htons(PORT_SEND);
//sin_send.sin_addr.s_addr = htonl(INADDR_BROADCAST);
inet_aton([@"224.4.0.1" UTF8String], &sin_send.sin_addr);

int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

int reuse = 1;
NSLog(@"reuse %d", setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse)));
NSLog(@"connect %d", connect(sock, (const struct sockaddr *) &sin_send, sizeof(sin_send)));

_sendSocket = CFSocketCreateWithNative(kCFAllocatorDefault, sock, kCFSocketWriteCallBack, socketWriteCallBack, &context);

if (!CFSocketIsValid(_sendSocket)) {
NSLog(@"Send socket is not valid");
return;
}

// Disable "nagling"
CFSocketNativeHandle ssock = CFSocketGetNative(_sendSocket);
int i = -1;
setsockopt(ssock, IPPROTO_TCP, TCP_NODELAY, (char*) &i, sizeof(int));

// Enable broadcast
int broadcast = 1;
setsockopt(ssock, SOL_SOCKET, SO_BROADCAST, (char*) &broadcast, sizeof(int));

这是接收套接字:

    struct sockaddr_in sin_read;
memset(&sin_read, 0, sizeof(sin_read));
sin_read.sin_len = sizeof(sin_read);
sin_read.sin_family = AF_INET;
sin_read.sin_port = htons(PORT_READ);
//sin_read.sin_addr.s_addr = INADDR_ANY;
inet_aton([@"224.4.0.1" UTF8String], &sin_read.sin_addr);

int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

int reuse = 1;
NSLog(@"reuse %d", setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &reuse, sizeof(reuse)));
NSLog(@"bind %d", bind(sock, (const struct sockaddr *) &sin_read, sizeof(sin_read)));

int broadcast = 1;
setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*) &broadcast, sizeof(int));

int flags;
flags = fcntl(sock, F_GETFL);
NSLog(@"fcntl %d", fcntl(sock, F_SETFL, flags | O_NONBLOCK));

_readSocket = CFSocketCreateWithNative(kCFAllocatorDefault, sock, kCFSocketAcceptCallBack | kCFSocketDataCallBack | kCFSocketReadCallBack, socketReadCallBack, &context);

谢谢,弗兰克

最佳答案

解决方案是将我的监听套接字绑定(bind)到 INADDR_ANY,然后使用带有 IP_ADD_MEMBERSHIP 选项的 setsockopt 以确保它监听所需的 IP 地址。

    struct ip_mreq mreq;
memset(&mreq, 0, sizeof(mreq));
inet_aton([@"224.4.0.1" UTF8String], &mreq.imr_multiaddr);
mreq.imr_interface.s_addr = INADDR_ANY;
setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));

关于ios - 使用具有特定 IP 地址的 UDP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27613072/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com