Как определить IP-адрес отправителя пакета udp, полученного на устройстве iOS? - PullRequest
1 голос
/ 26 августа 2010

Как узнать IP-адрес отправителя пакета udp, который был получен на устройстве под управлением iOS 3.2 или выше?

Например, если на компьютере используется Python, я бы использовал SocketServer.UDPServer который принимает подкласс SocketServer.BaseRequestHandler, который определяет обратный вызов handle.Когда приходит пакет, вызывается обратный вызов, и IP-адрес отправителя будет в self.client_address, где self - это экземпляр SocketServer.BaseRequestHandler.

К сожалению, я не знаю, как извлечь эту информациюили получить доступ к связанному заголовку ip при программировании в Objective C и использовании платформ, предоставляемых для iOS.

В настоящее время единственное решение, которое у меня есть, - это явно записать ip отправителя в теле пакета udp, ноЯ бы предпочел не полагаться на то, что отправитель разместит эту информацию там, если мне не нужно.

1 Ответ

3 голосов
/ 26 августа 2010

Вы не упомянули, какой 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."
...