如标题中所述,我的connect()调用带有相应地址的unix域类型套接字导致错误ENOENT:没有这样的文件或目录.
两个套接字已正确初始化,并相应地创建和绑定套接字文件.服务器和客户端套接字在不同的进程中运行,但客户端进程是fork() - ed和execl() - ed.这也是我解析客户端和服务器套接字的地址,我用它来设置客户端套接字.服务器进程正在使用pthreads.
这是我的connect()尝试:
struct sockaddr_un address;
address.sun_family = AF_UNIX;
memcpy(address.sun_path, filepath.c_str(), filepath.length());
address.sun_path[filepath.length()] = '\0';
if(-1 == connect(this->unix_domain_descriptor_.descriptor(), \
(struct sockaddr*)&address, \
size))
{
global::ExitDebug(-1, "connect() failed", __FILE__, __LINE__);
return -1;
}
Run Code Online (Sandbox Code Playgroud)
我尝试了不同的大小值,例如:
// this is from unix(7) man page. It doesn't work neither with nor without "+1"
socklen_t size = offsetof(struct sockaddr_un, sun_path);
size += strlen(address.sun_path) + 1;
Run Code Online (Sandbox Code Playgroud)
// this is from one of my books about linux programming
socklen_t size = sizeof(address);
Run Code Online (Sandbox Code Playgroud)
// this is from a sample code which I found at the internet
socklen_t size = sizeof(address.sun_family) + strlen(address.sun_path);
Run Code Online (Sandbox Code Playgroud)
// Update 1:
socklen_t size = SUN_LEN(&address);
Run Code Online (Sandbox Code Playgroud)
// this is what I tried out after looking into the declaration
// of struct sockaddr_un
socklen_t size = strlen(address.sun_path);
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,除最后一个之外的所有初始化都会导致EINVAL:connect()的无效参数错误,我得到了ENOENT:没有这样的文件或目录只有最后一个.我甚至从互联网上尝试了整个例子,但没有成功.显然,使用size_t或int交换socklen_t 不会改变任何东西.
我已经检查了这个:
现在我想知道为什么手册页示例不起作用以及是否有更改未在linux.die.net或www.kernel.org上更新.我的操作系统是Debian Squeeze,如果它是相关的.
我有什么想法我做错了吗?以及如何解决?如果您需要更多代码或有疑问,请不要犹豫问我(虽然我不需要说明这一点,但这是我在这里的第一篇文章>.<).
顺便说一句,抱歉我的英语不好
解决了.我将在下面的额外答案中将其发布为清晰度.
引用glibc 手册:
\n\n\n\n\n您应该将本地命名空间中套接字地址的 LENGTH 参数计算为组件大小与文件名字符串的
\n\nsun_family字符串长度(不是分配大小!)的总和。这可以使用宏来完成SUN_LEN:\n
\n- 宏: int SUN_LEN (_struct sockaddr_un *_ PTR)
\n
\n 该宏计算本地命名空间中套接字地址的长度。
下面的示例使用了您认为失败的计算:
\n\nsize = (offsetof (struct sockaddr_un, sun_path)\n + strlen (name.sun_path) + 1);\nRun Code Online (Sandbox Code Playgroud)\n\n但你应该尝试一下这个宏。如果发生了变化,或者示例是错误的,那么该宏仍然很有可能按预期工作。如果是的话,你可以看看它的内部结构。乍一看,我觉得这个宏缺少+ 1所有示例中使用的部分。这与手册中的警告相匹配,使用 \xe2\x80\x9c而不是分配大小! \xe2\x80\x9d 正如你的帖子所说,如果没有这两者,这不起作用+ 1,但机会很小。
出于好奇,路径的长度是多少?您是否检查过结构中提供的字段是否足够大以容纳它?sizeof(address.sun_path)您的实施中有哪些内容?我想知道您是否可能复制到未保留的内存,并且部分路径在下一个函数调用时被覆盖。
| 归档时间: |
|
| 查看次数: |
10314 次 |
| 最近记录: |