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



我在基于网络安全的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 = %dn",
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,'', 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,'', 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() 方法失败的原因,而套接字和绑定方法不会给出任何错误。

我正在ios模拟器(iPhone 7 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_send()显示的x字符串是 185 个字符,不带空终止符。 因此,如果它被截断,则可能是您得到ENOENT错误的原因。

话虽如此,您错误地计算了sockaddr_un的大小,并将错误的地址大小传递给bind()sendto()。 此外,open_and_bind_socket()data_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 memoryn");
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: %sn", 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: %sn", strerror(errno));
close(sock);
free(unaddr);
return ~0;
}
if (0 != chmod(sname, 0666))
{
AGENT_DEBUG(LOG_ERR, "%s", "Unable to chmod socket: %sn", 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, '', 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 memoryn");
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: %sn", strerror(errno));
free(saun);
return ~0;
}
free(saun);
return 0;
}

或者,您根本不需要动态分配sockaddr_un

int open_and_bind_socket(int *sockfd, const char *sname)
{
*sockfd = -1;
struct sockaddr_un unaddr;
memset(&unaddr, 0, sizeof(unaddr));
unaddr.sun_family = AF_UNIX;
strncpy(unaddr.sun_path, sname, sizeof(unaddr.sun_path)-1);
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: %sn", strerror(errno));
return ~0;
}
if (bind(sock, (struct sockaddr*) &unaddr, unaddr.sun_len) < 0)
{
AGENT_DEBUG(LOG_ERR, "%s", "Failed to bind the socket: %sn", strerror(errno));
close(sock);
return ~0;
}
if (0 != chmod(sname, 0666))
{
AGENT_DEBUG(LOG_ERR, "%s", "Unable to chmod socket: %sn", strerror(errno));
close(sock);
return ~0;
}
//unlink(sname);
*sockfd = sock;
return 0;
}
int data_send(int sockfd, tsIpcMsg *pMsgData)
{
// this is a buffer overflow waiting to happen!
memset(x, '', sizeof(x));
strcpy(x, buffer);
strcat(x, "/AGENTSOCKET");
struct sockaddr_un saun;
memset(&saun, 0, sizeof(saun));
saun.sun_family = AF_UNIX;    
strncpy(saun.sun_path, x, sizeof(saun.sun_path)-1);
// alternatively this is safer:
// snprintf(saun.sun_path, sizeof(saun.sun_path), "%s/AGENTSOCKET", buffer); 
saun.sun_len = SUN_LEN(&saun);
if (sendto(sockfd, (void*)pMsgData, sizeof(*pMsgData) + pMsgData->dataLen, 0, (struct sockaddr *) &saun, saun.sun_len) < 0)
{
AGENT_DEBUG(LOG_ERR, "%s", "Failed to send message from thread to main: %sn", strerror(errno));
return ~0;
}
return 0;
}

最新更新