2016-01-29 18 views
6

Mam pewną logikę, która działa przez utworzenie gniazda domeny uniksowej i nie ma żadnych problemów podczas uruchamiania w normalnej aplikacji. Jednak gdy uruchomię to dla rozszerzenia aplikacji, otrzymam -1 z errno = 48 ("Adres już w użyciu") z bind().Wiązanie gniazda domeny uniksowej w rozszerzeniu iOS kończy się niepowodzeniem z errno 48 (Adres już w użyciu)

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 

Lokalizacja wrócił do katalogu biblioteki jest:

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

Myślę, że powodem jest to zawodzi, ponieważ jest to jakiś specjalny położenie w stosunku do katalogu biblioteki dla aplikacji.

Jeśli ktoś ma jakieś pomysły, dlaczego tak się dzieje lub jakikolwiek sposób obejścia problemu, doceniam to.

AKTUALIZACJA: Próbowałem z katalogu pamięci podręcznych (NSCachesDirectory), ale teraz otrzymuję errno 3 (brak takiego procesu).

+0

Najpierw myślę, że adres jest naprawdę w użyciu. iOS może inicjować/zabijać rozszerzenia na żądanie, więc gniazdo powiązane w poprzednim połączeniu może nie zostać zwolnione podczas następnego połączenia. Dlaczego potrzebny jest program nasłuchujący gniazda domeny w kodzie rozszerzenia? –

+0

Wygląda na to, że masz rację. Początkowo myślałem, że to nie problem, ale w moim kodzie pojawił się drugi problem maskujący prawdziwy problem. Myślę, że teraz to zrozumiałem. – Locksleyu

+0

Chcę dać (Alex Skalozub) reputację +50, ale nie jestem pewien jak. Może powinieneś opublikować pełną odpowiedź z tym samym komentarzem co Twój komentarz? Lub możemy pozwolić, aby administrator sobie z tym poradził. – Locksleyu

Odpowiedz

3

Najpierw myślę, że adres jest naprawdę w użyciu.

System iOS może tworzyć lub zabijać rozszerzenia na żądanie, więc gniazdo powiązane w poprzednim połączeniu może nie zostać zwolnione podczas następnego połączenia.

+0

Dzięki! To był plus kombinacji innego problemu, który utrudniał triage, ale udało mi się to ustalić! – Locksleyu

0

Myślę, że najpierw należy zwolnić pierwszy obiekt, a następnie zadzwonić do następnego.

0

Jeśli chcesz, aby nowe gniazdo było przymocowane przymusowo, możesz użyć opcji gniazda SO_REUSEADDR.

Możesz użyć setsockopt() jak poniżej, aby ustawić SO_REUSEADDR.

int reuse = 1; 

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