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

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

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

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

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


person apalopohapa    schedule 25.08.2010    source источник


Ответы (1)


Вы не указали, какой API вы используете для получения пакета. Не записывайте IP-адрес в сам пакет, потому что пакет может пройти несколько трансляций сетевых адресов, прежде чем он попадет к вам.

Для выполнения этой задачи вы можете использовать обычные сокеты BSD. Есть также несколько классов Foundation, которые обертывают сокеты 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."
person dreamlax    schedule 26.08.2010
comment
Обратите внимание на параметр recvfrom fromAddr — это интересная часть. Он заполняется адресом/портом отправителя. - person Frank Shearar; 01.09.2010