从 iOS 扩展中绑定 Unix 域套接字失败,错误号为 48(地址已在使用中)
Binding a Unix Domain Socket from within an iOS extension fails with errno 48 (Address already in use)
我有一些逻辑可以通过创建 Unix 域套接字来工作,并且在 运行 普通应用程序中没有任何问题。但是,当我 运行 这是一个应用程序扩展时,我从 bind().
得到一个 -1 和 errno = 48 ("Address already in use")
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),但现在我得到错误号 3(没有这样的过程)。
初步猜测地址确实在使用中。
iOS 可能会 instantiate/kill 按需扩展,因此在执行下一次调用时可能不会释放上一次调用中绑定的套接字。
我觉得你应该先释放第一个对象,然后再调用下一个。
如果要强制绑定新套接字,可以使用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");
}
我有一些逻辑可以通过创建 Unix 域套接字来工作,并且在 运行 普通应用程序中没有任何问题。但是,当我 运行 这是一个应用程序扩展时,我从 bind().
得到一个 -1 和 errno = 48 ("Address already in use")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),但现在我得到错误号 3(没有这样的过程)。
初步猜测地址确实在使用中。
iOS 可能会 instantiate/kill 按需扩展,因此在执行下一次调用时可能不会释放上一次调用中绑定的套接字。
我觉得你应该先释放第一个对象,然后再调用下一个。
如果要强制绑定新套接字,可以使用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");
}