2016-01-29 7 views
6

Unixドメインソケットを作成することで動作するロジックがあり、通常のアプリケーションで実行しても問題はありません。しかし、これをappの拡張機能で実行すると、bind()からerrno = 48( "Address already in use")の-1が得られます。iOS拡張の中からUnixドメインソケットをバインドすると、errno 48(アドレスはすでに使用中)で失敗する

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 

場所は、ライブラリディレクトリのために返されます。私は、これはいくつかの特別な場所であるため、アプリのライブラリディレクトリに比べると、これは失敗している理由は、ある

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

と思います。

誰かがこれが起こっているかどうか、または回避策がある理由が分かっていれば、感謝します。

更新:私はキャッシュディレクトリ(NSCachesDirectory)で試しましたが、今はerrno 3(そのようなプロセスはありません)を取得しました。

+0

最初に推測されるのは、実際にアドレスが使用されていることです。 iOSはオンデマンドでエクステンションをインスタンシエート/強制終了する可能性があるため、次のコールが実行されたときに以前のコールでバインドされたソケットが解放されないことがあります。拡張コードにドメインソケットリスナーが必要なのはなぜですか? –

+0

あなたが正しいように見えます。もともと私はこれが問題ではないと思っていましたが、実際の問題を隠すコードには2番目の問題がありました。私はそれが今考え出されたと思う。 – Locksleyu

+0

私はあなたに(Alex Skalozub)+50の評判を与えたいが、どうしたらいいかわからない。たぶん、コメントと同じコメントで完全な回答を投稿するべきでしょうか?または、管理者に対処させることもできます。 – Locksleyu

答えて

3

最初の推測は、実際にアドレスが使用されていることです。

iOSはオンデマンドでエクステンションをインスタンシエート/強制終了することがあるため、次のコールが実行されたときに前のコールでバインドされたソケットが解放されないことがあります。

+0

ありがとう!これに加えて、トリアージを難しくしていた別の問題のコンビネーションがありましたが、私はそれを今考え出しました! – Locksleyu

0

最初に最初のオブジェクトを解放してから、次のオブジェクトを呼び出す必要があると思います。

0

新しいソケットを強制的にバインドする場合は、SO_REUSEADDRソケットオプションを使用できます。

次のようにsetsockopt()を使用してSO_REUSEADDRを設定できます。

int reuse = 1; 

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