Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 套接字创建失败,但Socket()和bind()方法不返回-1_Ios_C_Sockets - Fatal编程技术网

Ios 套接字创建失败,但Socket()和bind()方法不返回-1

Ios 套接字创建失败,但Socket()和bind()方法不返回-1,ios,c,sockets,Ios,C,Sockets,我正在开发基于网络安全的ios应用程序。我正在尝试为线程之间的通信创建一个本地套接字。我在ios应用程序中使用C语言来实现这一点 问题是,当我创建和绑定套接字时,它不会给出任何错误。但是当我试图通过这个套接字发送一些数据时,它失败了。套接字的创建和绑定代码如下: int open_and_bind_socket(int *sockfd, const char *sname) { //sname is socket name with full path size_t len = st

我正在开发基于网络安全的ios应用程序。我正在尝试为线程之间的通信创建一个本地套接字。我在ios应用程序中使用C语言来实现这一点

问题是,当我创建和绑定套接字时,它不会给出任何错误。但是当我试图通过这个套接字发送一些数据时,它失败了。套接字的创建和绑定代码如下:

int open_and_bind_socket(int *sockfd, const char *sname)
{
  //sname is socket name with full path
    size_t len = strlen (sname);

    size_t bytes = sizeof (struct sockaddr_un) + len + 1 - sizeof (((struct sockaddr_un *)0)->sun_path);

    struct sockaddr_un *unaddr = (struct sockaddr_un *)malloc (bytes);

     size_t size;

    if((*sockfd = socket (AF_LOCAL, SOCK_DGRAM, 0)) < 0)
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to open socket");
        return ~0;
    }

    unaddr->sun_family = AF_UNIX;
    unaddr->sun_len = bytes;
    memcpy(unaddr->sun_path, sname,len+1);

    size = (offsetof (struct sockaddr_un, sun_path)
                + strlen (unaddr->sun_path));

    if( bind(*sockfd,(struct sockaddr*)unaddr,size ) < 0)
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to bind the socket");
        AGENT_DEBUG(LOG_ERR, "Recvfrom MSG_PEEK Failure: %s, Socket Fd = %d\n",
                    strerror(errno), sockfd);
        return ~0;
    }

    if(0 != chmod(sname, 0666))
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Unable to chmod Socket");
        return ~0;
    }
     //unlink(sname);
    return 0;
}
int data_send(int sockfd, tsIpcMsg *pMsgData)
{
    memset(x,'\0', sizeof(x));
    strcpy(x, buffer);
    strcat(x,"/AGENTSOCKET");
    size_t len = strlen (x);

    size_t bytes = sizeof (struct sockaddr_un) + len + 1 - sizeof (((struct sockaddr_un *)0)->sun_path);

    struct sockaddr_un *saun = (struct sockaddr_un *)malloc (bytes);

    memset(saun, 0, sizeof(*saun));
    saun->sun_family = AF_UNIX;    
    saun->sun_len=bytes;
    memcpy(saun->sun_path, x,len+1);
    memset(x,'\0', sizeof(x));

    if(-1 == (sendto(sockfd,(void*)pMsgData, sizeof(tsIpcMsg)+pMsgData->dataLen , 0, (struct sockaddr *)saun, sizeof(*saun))))
   {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to send message from thread to main");
        return ~0;
    }
    return 0;
}
当我记录sendto()函数返回的errno时,它给出了值“2”,这意味着“不存在这样的文件或目录:路径名中的组件不存在,或者是悬空符号链接,或者路径名为空。”

因此,我认为套接字没有正确创建,这就是sendto()方法失败的原因,而socket和bind方法没有给出任何错误

我正在ios模拟器(iPhone7 plus)上运行此应用程序。套接字的路径如下所示: “/Users/Admin/Library/Developer/CoreSimulator/Devices/FC85979F-A627-4361-B4BD-DD794AB009C9/data/Containers/data/Application/C45B9A05-F482-4011-8EA0-947A8C489367/Documents/app/AGENTSOCKET”,其中AGENTSOCKET是套接字的名称

我正在创建目录结构直到应用程序文件夹,然后在创建套接字时将套接字名称附加到它,方法如下:

mkdir(path,0777);//path is till app directory
strcat(path, "/AGENTSOCKET");
有人能帮我解决这个问题吗


谢谢。

sun_path字段限制为92-108个字符(取决于平台),包括空终止符。为
data\u send()
显示的
x
字符串为185个字符,没有空终止符。因此,如果它被截断,这可能是您得到的
enoint
错误的原因

也就是说,您错误地计算了
sockaddr\u un
的大小,并将错误的地址大小传递给
bind()
sendto()
。另外,
open\u和\u bind\u socket()
data\u send()
正在泄漏内存

请尝试类似以下内容:

int open_and_bind_socket(int *sockfd, const char *sname)
{
    *sockfd = -1;

    //sname is socket name with full path
    size_t len = strlen (sname);

    size_t size = offsetof (struct sockaddr_un, sun_path) + len + 1;

    struct sockaddr_un *unaddr = (struct sockaddr_un *) malloc (size);
    if (!unaddr)
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to allocate memory\n");
        return ~0;
    }

    memset(unaddr, 0, size);
    unaddr->sun_family = AF_UNIX;
    memcpy(unaddr->sun_path, sname, len);
    unaddr->sun_len = SUN_LEN(unaddr);

    int sock = socket (AF_LOCAL, SOCK_DGRAM, 0);
    if (sock < 0)
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to create socket: %s\n", strerror(errno));
        free(unaddr);
        return ~0;
    }

    if (bind(sock, (struct sockaddr*)unaddr, unaddr->sun_len) < 0)
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to bind the socket: %s\n", strerror(errno));
        close(sock);
        free(unaddr);
        return ~0;
    }

    if (0 != chmod(sname, 0666))
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Unable to chmod socket: %s\n", strerror(errno));
        close(sock);
        free(unaddr);
        return ~0;
    }

    free(unaddr);

    //unlink(sname);

    *sockfd = sock;

    return 0;
}

int data_send(int sockfd, tsIpcMsg *pMsgData)
{
    // this is a buffer overflow waiting to happen!
    memset(x, '\0', sizeof(x));
    strcpy(x, buffer);
    strcat(x, "/AGENTSOCKET");

    size_t len = strlen (x);

    size_t size = offsetof (struct sockaddr_un, sun_path) + len + 1;

    struct sockaddr_un *saun = (struct sockaddr_un *) malloc (size);
    if (!saun)
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to allocate memory\n");
        return ~0;
    }

    memset(saun, 0, size);
    saun->sun_family = AF_UNIX;    
    memcpy(saun->sun_path, x, len);
    saun->sun_len = SUN_LEN(saun);

    if (sendto(sockfd, (void*)pMsgData, sizeof(tsIpcMsg) + pMsgData->dataLen, 0, (struct sockaddr *)saun, saun->sun_len) < 0)
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to send message from thread to main: %s\n", strerror(errno));
        free(saun);
        return ~0;
    }

    free(saun);
    return 0;
}

sun_path
字段限制为92-108个字符(取决于平台),包括空终止符。为
data\u send()
显示的
x
字符串为185个字符,没有空终止符。因此,如果它被截断,这可能是您得到的
enoint
错误的原因

也就是说,您错误地计算了
sockaddr\u un
的大小,并将错误的地址大小传递给
bind()
sendto()
。另外,
open\u和\u bind\u socket()
data\u send()
正在泄漏内存

请尝试类似以下内容:

int open_and_bind_socket(int *sockfd, const char *sname)
{
    *sockfd = -1;

    //sname is socket name with full path
    size_t len = strlen (sname);

    size_t size = offsetof (struct sockaddr_un, sun_path) + len + 1;

    struct sockaddr_un *unaddr = (struct sockaddr_un *) malloc (size);
    if (!unaddr)
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to allocate memory\n");
        return ~0;
    }

    memset(unaddr, 0, size);
    unaddr->sun_family = AF_UNIX;
    memcpy(unaddr->sun_path, sname, len);
    unaddr->sun_len = SUN_LEN(unaddr);

    int sock = socket (AF_LOCAL, SOCK_DGRAM, 0);
    if (sock < 0)
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to create socket: %s\n", strerror(errno));
        free(unaddr);
        return ~0;
    }

    if (bind(sock, (struct sockaddr*)unaddr, unaddr->sun_len) < 0)
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to bind the socket: %s\n", strerror(errno));
        close(sock);
        free(unaddr);
        return ~0;
    }

    if (0 != chmod(sname, 0666))
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Unable to chmod socket: %s\n", strerror(errno));
        close(sock);
        free(unaddr);
        return ~0;
    }

    free(unaddr);

    //unlink(sname);

    *sockfd = sock;

    return 0;
}

int data_send(int sockfd, tsIpcMsg *pMsgData)
{
    // this is a buffer overflow waiting to happen!
    memset(x, '\0', sizeof(x));
    strcpy(x, buffer);
    strcat(x, "/AGENTSOCKET");

    size_t len = strlen (x);

    size_t size = offsetof (struct sockaddr_un, sun_path) + len + 1;

    struct sockaddr_un *saun = (struct sockaddr_un *) malloc (size);
    if (!saun)
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to allocate memory\n");
        return ~0;
    }

    memset(saun, 0, size);
    saun->sun_family = AF_UNIX;    
    memcpy(saun->sun_path, x, len);
    saun->sun_len = SUN_LEN(saun);

    if (sendto(sockfd, (void*)pMsgData, sizeof(tsIpcMsg) + pMsgData->dataLen, 0, (struct sockaddr *)saun, saun->sun_len) < 0)
    {
        AGENT_DEBUG(LOG_ERR, "%s", "Failed to send message from thread to main: %s\n", strerror(errno));
        free(saun);
        return ~0;
    }

    free(saun);
    return 0;
}

这是一种计算地址结构所需大小的奇怪方法。
偏移(struct sockaddr\u un,sun\u path)+len+1
不是更简单更清晰吗?此外,POSIX没有为
struct sockaddr\u un
记录
sun\u len
成员,即使是iOS特有的功能,我也找不到它的文档。如果它确实存在,那么它不太可能用于应用程序。什么是
x
。。。?您发送的
数据以
memset(x,'\0',sizeof(x))
开头。。。但是它是什么?@JohnBollinger:per:“在Linux上,上面的
offsetof()
表达式与
sizeof(sau family_t)
的值相同,但是一些其他实现在
sun\u path
之前包含其他字段,因此
offsetof()
表达式更方便地描述了地址结构的大小。”这是一种计算地址结构所需大小的奇怪方法。
偏移(struct sockaddr\u un,sun\u path)+len+1
不是更简单更清晰吗?此外,POSIX没有为
struct sockaddr\u un
记录
sun\u len
成员,即使是iOS特有的功能,我也找不到它的文档。如果它确实存在,那么它不太可能用于应用程序。什么是
x
。。。?您发送的
数据以
memset(x,'\0',sizeof(x))
开头。。。但是它是什么?@JohnBollinger:per:“在Linux上,上面的
offsetof()
表达式与
sizeof(sau family_t)
的值相同,但是一些其他实现在
sun\u path
之前包含其他字段,因此
offsetof()
表达式更方便地描述了地址结构的大小。”谢谢你的帮助,第一个解决方案对我有效。我有必要使用malloc,因为我创建套接字的路径太长,无法进入sun_路径,因为默认情况下,它只允许104个字符。@S.Vishwakarma在大多数Linux系统上,
sun_路径
为108,并且显示:“路径名的长度(包括终止的空字节)不应超过sun_路径的大小。。。在编写便携式应用程序时,请记住,有些实现的sun_路径短至92字节。“我预计iOS也会有类似的限制。如果
bind
sendto
接受更长的
sun\u路径
值,这是不可移植的行为。感谢您的帮助,第一个解决方案对我有效。我有必要使用malloc,因为我创建套接字的路径太长,无法进入sun_路径,因为默认情况下,它只允许104个字符。@S.Vishwakarma在大多数Linux系统上,
sun_路径
为108,并且显示:“路径名的长度(包括终止的空字节)不应超过sun_路径的大小。。。在编写便携应用程序时,请记住,某些实现的sun_路径最短为92字节。“我希望iOS中也会有类似的限制。如果
bind
sendto
接受更长的
sun_路径
值,则这不是便携行为。