IPC QLocalSocket -> C,为啥我的连接失败?连接失败:[2](没有这样的文件?!)
Posted
技术标签:
【中文标题】IPC QLocalSocket -> C,为啥我的连接失败?连接失败:[2](没有这样的文件?!)【英文标题】:IPC QLocalSocket -> C, why is my connect failing ? connect failed: [2] (no such file?!)IPC QLocalSocket -> C,为什么我的连接失败?连接失败:[2](没有这样的文件?!) 【发布时间】:2015-10-20 09:15:53 【问题描述】:我正在运行这个示例http://doc.qt.io/qt-5/qtcore-ipc-localfortuneserver-example.html
使用cat <socket_name>
工作正常,我什至设法连接到python。
但是不幸的是,这失败了。 -> connect() 失败:[2][没有这样的文件或目录]? W H Y ¿
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#define SOCK_PATH "/Users/Name/socket"
int main(void)
int sockfd = 0,n = 0, err = 0;
char recvBuff[1024];
struct sockaddr_un serv_addr;
const char* const pcSocketName = SOCK_PATH;
memset(recvBuff, '0' ,sizeof(recvBuff));
if((sockfd = socket(AF_UNIX, SOCK_STREAM, 0))< 0)
printf("\n Error : Could not create socket \n");
return 1;
serv_addr.sun_family = AF_UNIX;
serv_addr.sun_path[0] = '\0';
strncpy(serv_addr.sun_path+1, pcSocketName, strlen(pcSocketName));
err = connect(sockfd, (struct sockaddr*) &serv_addr, sizeof(serv_addr));
if(0 != err)
printf("connect() failed: [%d][%s]\n", errno, strerror(errno));
return(-1);
while((n = read(sockfd, recvBuff, sizeof(recvBuff)-1)) > 0)
recvBuff[n] = 0;
if(fputs(recvBuff, stdout) == EOF)
printf("\n Error : Fputs error");
printf("\n");
if( n < 0)
printf("\n Read Error \n");
printf("Over..\n");
return 0;
我在 MacOS 上运行,使用 gcc 构建。这段代码的一部分来自网络上的不同地方。
【问题讨论】:
【参考方案1】:socket路径复制行错误:
strncpy(serv_addr.sun_path+1, pcSocketName, strlen(pcSocketName));
您想将pcSocketName
复制到serv_addr.sun
。此外,保护strlen(pcSocketName)
在这里没有任何意义。你可以只使用
strcpy(serv_addr.sun_path, pcSocketName);
在简单的例子中,strcpy
是安全的,如果我们确定SOCK_PATH
的长度足够小以适合缓冲区serv_addr.sun_path
。但是,为了避免意外错误或在字符串长度可能变化的更复杂的情况下,防止潜在的溢出是有意义的。函数strncpy
可用于从pcSocketName
复制不超过sizeof(serv_addr.sun_path) - 1
字节。一个字节是为零终止字符保留的。如果在strncpy
中达到长度限制,则不会附加最后一个空字符。所以,应该手动设置:
serv_addr.sun_path[sizeof(serv_addr.sun_path) - 1] = '\0';
strncpy(serv_addr.sun_path, pcSocketName, sizeof(serv_addr.sun_path) - 1);
我猜你的代码是基于Can not connect to Linux "abstract" unix socket
这导致了最初的连接问题。 sun_path[]
中的第一个字节应该为零 (serv_addr.sun_path[0] = '\0';
) 才能使用 抽象命名空间 UNIX 套接字。然而,这样的抽象命名空间是一个不可移植的 Linux 扩展:
QLocalSocket
即使在 Linux 上也不支持它:QTBUG-16090
所以,QLocalSocket
与文件系统套接字一起工作。在 C 中,此类套接字应仅通过 sun_path
中的以 null 结尾的文件系统路径名来访问。
【讨论】:
关于保护,我认为一种或另一种就足够了,但两者都是多余的吗? @thomas 是的,您可以使用strcpy
(您的路径长度足够小,您可以手动设置)或者确保路径适合serv_addr.sun_path
,您可以使用strncpy
并手动设置最后一个零字节。顺便说一句,为了澄清连接问题,我猜您的代码来自关于abstract
套接字***.com/questions/11640826/… 的帖子您会发现抽象套接字不使用真实文件名,但您有可以与cat
一起使用的真实文件。 以上是关于IPC QLocalSocket -> C,为啥我的连接失败?连接失败:[2](没有这样的文件?!)的主要内容,如果未能解决你的问题,请参考以下文章