我正在使用unix本地套接字上的数据报实现一个简单的服务(AF_UNIX地址系列,即不是UDP).服务器绑定到公共地址,它接收请求就好了.不幸的是,当谈到回复时,sendto
除非客户端也被绑定,否则失败.(常见的错误是Transport endpoint is not connected
).
绑定到一些随机名称(基于文件系统或抽象)的工作.但我想避免这种情况:我是谁保证我选择的名字不会碰撞?
unix套接字的流模式文档告诉我们,connect
如果它们还没有抽象名称,那么它们将在时间分配给它们.这种功能是否适用于面向数据报的套接字?
我引用的unix(7)手册页有关于autobind UNIX套接字的信息:
如果bind(2)调用将addrlen指定为sizeof(sa_family_t),或者为未明确绑定到地址的套接字指定了SO_PASSCRED套接字选项,则套接字将自动生成为抽象地址.
这就是Linux内核检查地址长度等于sizeof(short)的原因,因为sa_family_t是一个简短的.Rob的优秀答案引用的另一个unix(7)手册页说客户端套接字总是在连接上自动响应,但由于SOCK_DGRAM套接字是无连接的(尽管在它们上面调用了连接),我相信这只适用于SOCK_STREAM套接字.
另请注意,在提供自己的抽象命名空间套接字名称时,此命名空间中的套接字地址由sun_path中指定长度的地址结构所覆盖的其他字节给出.
struct sockaddr_un me; const char name[] = "\0myabstractsocket"; me.sun_family = AF_UNIX; // size-1 because abstract socket names are not null terminated memcpy(me.sun_path, name, sizeof(name) - 1); int result = bind(fd, (void*)&me, sizeof(me.sun_family) + sizeof(name) - 1);
sendto()同样应该限制地址长度,而不是传递sizeof(sockaddr_un).