2016-01-29 31 views
6

Ich habe eine Logik, die durch Erstellen eines Unix-Domain-Sockets funktioniert und keine Probleme bei der Ausführung in einer normalen App hat. Wenn ich dies jedoch für eine App-Erweiterung ausführe, bekomme ich eine -1 mit errno = 48 ("Address is in use") von der bind().Das Binden eines Unix-Domain Sockets innerhalb einer iOS-Erweiterung schlägt fehl mit errno 48 (Adresse wird bereits verwendet)

NSArray *applicationSupportDirectoryPaths = 
NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, 
            NSUserDomainMask, YES); 

int fd = socket(AF_UNIX, SOCK_STREAM, 0); // returns a non-zero value 

NSString *loc = [applicationSupportDirectoryPaths[0] stringByAppendingPathComponent:@"usd"]; 
struct sockaddr_un addr; 
memset(&addr, 0, sizeof(addr)); 
addr.sun_family = AF_UNIX ; 
strncpy(addr.sun_path, [loc UTF8String], sizeof(addr.sun_path)-1); 
int bindres = bind(fd, (struct sockaddr*)&addr, sizeof(addr)); // returns -1, error is 48 

Die Lage für das Bibliotheksverzeichnis zurückgegeben wird:

/var/mobile/Containers/Data/PluginKitPlugin/A8110BA2-5AE7-42C1-84DA-2A9B303C7277/Library/ 

Ich denke, der Grund, dies fehlschlägt, weil dies eine besondere Lage ist, als für eine App zum Bibliotheksverzeichnis verglichen.

Wenn jemand irgendwelche Ideen hat, warum das passiert oder irgendwelche Workarounds, ich schätze es.

UPDATE: Ich habe versucht, mit dem Cache-Verzeichnis (NSCachesDirectory), aber jetzt bekomme ich errno 3 (kein solcher Prozess).

+0

Erste Schätzung ist Adresse wirklich in Gebrauch ist. iOS kann Erweiterungen bei Bedarf instanzieren/beenden, sodass der Socket, der im vorherigen Aufruf gebunden wurde, möglicherweise nicht freigegeben wird, wenn der nächste Aufruf ausgeführt wird. Warum benötigen Sie einen Domänen-Socket-Listener im Erweiterungscode? –

+0

Sieht aus, als hättest du recht gehabt. Ursprünglich hatte ich gedacht, das wäre nicht das Problem, aber es gab ein zweites Problem in meinem Code, das das eigentliche Problem maskierte. Ich denke, ich habe es jetzt herausgefunden. – Locksleyu

+0

Ich möchte dir (Alex Skalozub) den +50 Ruf geben, aber nicht sicher wie. Vielleicht solltest du eine vollständige Antwort mit demselben Kommentar wie deinen Kommentar posten? Oder wir können einen Admin damit umgehen lassen. – Locksleyu

Antwort

3

Erste Rate ist Adresse ist wirklich in Verwendung.

iOS kann Erweiterungen bei Bedarf instanziieren/beenden, sodass der im vorherigen Aufruf gebundene Socket möglicherweise nicht freigegeben wird, wenn der nächste Aufruf ausgeführt wird.

+0

Danke! Es war dies und eine Kombination aus einem anderen Thema, das Triage schwierig machte, aber ich habe es jetzt herausgefunden! – Locksleyu

0

Ich denke, Sie sollten zuerst das erste Objekt freigeben und dann das nächste aufrufen.

0

Wenn der neue Socket zwangsweise gebunden werden soll, können Sie die Socket-Option SO_REUSEADDR verwenden.

Sie können setsockopt() wie folgt verwenden, um SO_REUSEADDR festzulegen.

int reuse = 1; 

if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) < 0) 
{ 
    perror("setsockopt(SO_REUSEADDR) failed"); 
}