如何识别 iOS 设备上收到的 udp 数据包的发送者 IP 地址?

发布于 2024-09-16 11:12:14 字数 452 浏览 5 评论 0原文

如何找出运行 iOS 3.2 或更高版本的设备上收到的 udp 数据包的发送者 IP 地址?

例如,如果在计算机上使用 Python,我将使用 SocketServer.UDPServer,它采用 SocketServer.BaseRequestHandler 的子类,该子类定义了句柄打回来。当数据包到达时,回调将被调用,发送者的 IP 地址将位于 self.client_address 中,其中 selfSocketServer.BaseRequestHandler 实例。

不幸的是,我不知道在 Objective C 中编程并使用为 iOS 提供的框架时如何提取此信息或访问关联的 ip 标头。

现在我唯一的解决方案是在 udp 数据包的主体上显式写入发送者的 ip,但如果不需要的话,我宁愿不依赖发送者将该信息放在那里。

How to find out the sender's ip address of a udp packet that was received on a device running iOS 3.2 or higher?

For example, if using Python on a computer, I'd use SocketServer.UDPServer which takes a subclass of SocketServer.BaseRequestHandler which defines the handle callback. When a packet arrives, the callback is called and the sender's ip address would be in self.client_address, where self is the SocketServer.BaseRequestHandler instance.

Unfortunately, I don't know how to extract this information or gain access to the associated ip header when programming in Objective C and using the frameworks provided for iOS.

Right now the only solution I have is to explicitly write the sender's ip on the body of the udp packet, but I'd rather not rely on the sender putting that information there if I don't have to.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

漫雪独思 2024-09-23 11:12:14

您没有提到您使用什么 API 来接收数据包。不要将 IP 地址写入数据包本身,因为数据包在到达您之前可能会经过多次网络地址转换。

您可以使用常规 BSD 套接字来完成此任务。还有一些围绕 BSD 套接字的基础类,但我个人没有使用过它们,所以我不能给你一个像样的例子。

// for IPv4 (IPv6 is a little different)

ssize_t received;
char buffer[0x10000];
struct sockaddr_in listenAddr;
struct sockaddr_in fromAddr;
socklen_t fromAddrLen = sizeof fromAddr;

listenAddr.sin_family = AF_INET;
listenAddr.sin_port = htons(12345); // change to whatever port
listenAddr.sin_addr.s_addr = htonl(INADDR_ANY);

int s = socket(AF_INET, SOCK_DGRAM, 0); // create UDP socket
if (s == -1)
    exit(1); // failed to create socket

if (bind(s, (struct sockaddr *) &listenAddr, sizeof listenAddr))
    exit(2); // failed to bind to port 12345 for any address

received = recvfrom(s, buffer, sizeof buffer, 0, (struct sockaddr *)&fromAddr, &fromAddrLen);
if (received == -1)
    exit(3); // some failure trying to receive data

// check the contents of buffer, the address of the source will be in
// fromAddr.sin_addr.s_addr but only if (fromAddrLen == sizeof fromAddr)
// after the call to recvfrom.

char display[16] = {0};
inet_ntop(AF_INET, &fromAddr.sin_addr.s_addr, display, sizeof display);

NSLog (@"The source is %s.", display);
// could show "The source is 201.19.91.102."

You didn't mention what API you are using to receive the packet. Don't write the IP address into the packet itself because the packet may go through a number of network address translations before it gets to you.

You can use regular BSD sockets to acheive this task. There are also a few Foundation classes that wrap around BSD sockets, but I haven't used them personally, so I can't give you a decent example.

// for IPv4 (IPv6 is a little different)

ssize_t received;
char buffer[0x10000];
struct sockaddr_in listenAddr;
struct sockaddr_in fromAddr;
socklen_t fromAddrLen = sizeof fromAddr;

listenAddr.sin_family = AF_INET;
listenAddr.sin_port = htons(12345); // change to whatever port
listenAddr.sin_addr.s_addr = htonl(INADDR_ANY);

int s = socket(AF_INET, SOCK_DGRAM, 0); // create UDP socket
if (s == -1)
    exit(1); // failed to create socket

if (bind(s, (struct sockaddr *) &listenAddr, sizeof listenAddr))
    exit(2); // failed to bind to port 12345 for any address

received = recvfrom(s, buffer, sizeof buffer, 0, (struct sockaddr *)&fromAddr, &fromAddrLen);
if (received == -1)
    exit(3); // some failure trying to receive data

// check the contents of buffer, the address of the source will be in
// fromAddr.sin_addr.s_addr but only if (fromAddrLen == sizeof fromAddr)
// after the call to recvfrom.

char display[16] = {0};
inet_ntop(AF_INET, &fromAddr.sin_addr.s_addr, display, sizeof display);

NSLog (@"The source is %s.", display);
// could show "The source is 201.19.91.102."
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文