2009-08-18 7 views
2

Ich habe eine iPhone-Anwendung/ein Projekt geerbt, die eine Socket-Verbindung zu einem anderen Gerät öffnet (denke Web-Cam). Dies funktioniert gut, solange das Gerät über das WLAN-Netzwerk erreichbar ist. Wenn es jedoch nicht erreichbar ist, hängt die Anwendung "connect" aufrufen.Testen der Erreichbarkeit der IP-Adresse vom iPhone

(Fehler für Klarheit gezupft zu überprüfen.)

-(void)connect_to_control:(NSTimer*) timer 

{

clientsock_fd = socket(AF_INET, SOCK_STREAM, 0); 
int no_delay = 1; 
setsockopt(clientsock_fd, IPPROTO_TCP, TCP_NODELAY, &no_delay, 4); 

struct sockaddr_in the_addr; 
memset((void *)&the_addr, 0, sizeof(the_addr)); 
the_addr.sin_family = AF_INET; 
the_addr.sin_port = htons(25556); 
const char* server_addr = "192.168.3.22"; 
unsigned long ip_addr = inet_addr(server_addr); 


the_addr.sin_addr.s_addr = ip_addr; 
int err_test = connect(clientsock_fd, (const struct sockaddr*)&the_addr, sizeof(the_addr)); 

}

Mein erster Gedanke zu "ping", war die Adresse, um zu sehen, ob es erreichbar ist. Bisher habe ich Apples "Reachability" -Stichprobe entdeckt, aber das bestimmt NICHT, ob eine Adresse erreichbar ist, nur wenn das Netzwerk erreichbar ist (außer im Simulator) und ein altes Apple-Beispiel "SimplePing", das Headerdateien verwendet, die nicht sind im iPhone SDK enthalten.

Ich habe Jahrzehnte C++/C# -Erfahrung, aber ich bin ein iPhone Noob versuchen, aus der kleinen Firma eines Freundes zu helfen, einige Sachen rechtzeitig für eine wichtige Messe zu debuggen. Danke im Voraus.

Antwort

0

welchem ​​Grund auch immer, ich war nicht in der Lage, eine nicht blockierende Lösung zu erhalten, indem man "Auswählen" verwendet. (Aber ich danke Ihnen beiden für Ihre hilfreichen Antworten.) Am Ende habe ich eine der Socket-Optionen verwendet, mit der ich eine kürzere Zeitüberschreitung angeben konnte.

setsockopt(clientsock_fd, IPPROTO_TCP, TCP_CONNECTIONTIMEOUT, &timeout, sizeof(timeout)); 

Im Interesse der Vollständigkeit, ist das, was ich am Ende mit (Fehlern zur Klarheit entfernt Prüfung):

-(void)connect_to_control:(NSTimer*) timer 

{

clientsock_fd = socket(AF_INET, SOCK_STREAM, 0); 
int no_delay = 1; 
int result = setsockopt(clientsock_fd, IPPROTO_TCP, TCP_NODELAY, &no_delay, 4); 

// *** Set timeout value to stop hanging *** 
struct timeval timeout; 
timeout.tv_sec =1; 
timeout.tv_usec =0; 
result = setsockopt(clientsock_fd, IPPROTO_TCP, TCP_CONNECTIONTIMEOUT, &timeout, sizeof(timeout)); 

struct sockaddr_in the_addr; 
memset((void *)&the_addr, 0, sizeof(the_addr)); 
the_addr.sin_family = AF_INET; 
the_addr.sin_port = htons(25556); 
const char* server_addr = "192.168.3.22"; 
unsigned long ip_addr = inet_addr(server_addr); 
the_addr.sin_addr.s_addr = ip_addr; 

int err_test = connect(clientsock_fd, (const struct sockaddr*)&the_addr, sizeof(the_addr)); // hangs here when address can't be reached! 

HINWEIS: Ich musste Aktualisieren Sie auf OS 3.0, um zu verwenden. TCP_CONNECTIONTIMEOUT ist in "tcp.h" den OS 3.0 SDK-Headern definiert, aber nicht in OS 2.1. Es ist nicht in den Kopfzeilen des Simulators definiert, sondern nur in den Gerätekopfzeilen.

3

Siehe this question, um zu erfahren, wie ein Socket in den nicht blockierenden Modus versetzt wird.

Dies ist wahrscheinlich das, was Sie tun möchten, da ein Host auf Pings reagieren kann, obwohl er nicht auf einen bestimmten Socket hört und umgekehrt.

+0

Diese Antwort bietet nicht wirklich die vollständigen Details, wie es geht. – corydoras

1

Zum einen den Sockel in nicht blockierenden Modus versetzt, bedeutet dies ein connect wird immer sofort zurück:

lags = fcntl(sock,F_GETFL,0); 
fcntl(sock,F_SETFL, flags | O_NONBLOCK) 

Dann Sie die Select-Anweisung mit einem Timeout-Wert verwenden, um zu überprüfen, ob die Verbindung noch succeded hat:

select(FD_SETSIZE,0,&wset,0,&timeout) 

Sie vollständige Erklärung finden von non blocking sockets here

+0

OP hier: Danke, das sieht vielversprechend aus. Ich versuche es heute Morgen. –

Verwandte Themen