重用 linux 抽象命名空间套接字
Posted
技术标签:
【中文标题】重用 linux 抽象命名空间套接字【英文标题】:Reusing linux abstract namespace socket 【发布时间】:2017-06-06 17:36:15 【问题描述】:我想在一个服务器会话期间重用一个抽象套接字地址。我试图关闭套接字并再次绑定它们,但它不起作用。
server.c:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
int main()
struct sockaddr_un workmanaddr;
workmanaddr.sun_family=AF_UNIX;
strcpy(workmanaddr.sun_path+1,"name");
workmanaddr.sun_path[0]='0';
char buf[255];
int sd = socket(AF_UNIX, SOCK_DGRAM, 0);
if(sd <0)
perror("socket() error");
exit(2);
if((bind(sd , (struct sockaddr *)&workmanaddr,sizeof(workmanaddr)))<0)
perror("bind() error");
exit(3);
while(true)
recv(sd, buf, sizeof(buf), 0);
printf("%s\n",buf);
close(sd);
sd = socket(AF_UNIX, SOCK_DGRAM, 0);
if(sd <0)
perror("socket() error");
exit(2);
if((bind(sd , (struct sockaddr*)&workmanaddr,sizeof(workmanaddr)))<0)
perror("bind() error");
exit(3);
return 0;
client.c:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
int main(int argc, char *argv[])
char _path[108]="name";
struct sockaddr_un tempadres = 0;
int tmpsock;
tmpsock = socket(AF_UNIX, SOCK_DGRAM, 0);
if(tmpsock<0)
perror("socket() error");
exit(2);
tempadres.sun_family=AF_UNIX;
strcpy(tempadres.sun_path+1,_path);
tempadres.sun_path[0]='0';
if((connect(tmpsock, (struct sockaddr *)&tempadres,sizeof(tempadres)))<0)
perror("connect() error");
exit(3);
char buf[255];
scanf("%s",buf);
if(send(tmpsock, buf, sizeof(buf), 0)<0)
perror("send() error");
exit(4);
return 0;
我应该怎么做才能使其可以多次重复使用?有什么建议吗?
【问题讨论】:
“它不起作用”是什么意思?您预计会发生什么以及实际会发生什么? 相关:unix.stackexchange.com/questions/216784/…tempadres.sun_path[0]='0';
'0' 不是空字节!
【参考方案1】:
在这一行中:tempadres.sun_path[0]='0'
,'0'
不是空字节,这是抽象套接字对sun_path
字段的第一个字节所要求的。所以它不会被视为抽象套接字。将其更改为 tempadres.sun_path[0]=0
或 tempadres.sun_path[0]='\0'
。
PS:你的server.c
还有一个问题,你没有把workmanaddr
归零,所以sun_path
很可能包含垃圾值,因为它是在堆栈上分配的即使您调用了strcpy(workmanaddr.sun_path+1,"name");
并附加了一个空字节,因为sun_path
中的所有剩余字节都定义了套接字的“名称”。这会导致与客户端的套接字名称不同,从而导致客户端拒绝连接。
【讨论】:
以上是关于重用 linux 抽象命名空间套接字的主要内容,如果未能解决你的问题,请参考以下文章