unix 域 套接字 示例

这个与AF_INET不同地方在于,客户端也要用bind绑定一下,不要靠connect分配,不然服务器是无法知道客户用的是哪个套接字文件

服务器端

[ssj@main test]$ cat AFunixserver.c
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>

#define PATH "/home/ssj/source/test/connect.socket"
#define STALE 30
#define MAX 1024

void my_turn(char *p)
{
if (p == NULL)return;
while( *p != '')
{
if( *p >= (char)0x61 && *p <= (char)0x7a)
*p=(char)((int)*p-(int)0x20);
p++;
}
}

int init(int *lfd,char *path)
{
int fd,len;
struct sockaddr_un un;

if((fd=socket(AF_UNIX,SOCK_STREAM,0))==-1)
{perror("Fail to socket");return -1;}

unlink(path);
memset(&un,0,sizeof(un));
un.sun_family=AF_UNIX;
strcpy(un.sun_path,path);

len=offsetof(struct sockaddr_un,sun_path)+strlen(path);
if(bind(fd,(struct sockaddr *)&un,len)==-1)
{perror("Fail to bind");goto err;}

if(listen(fd,10)==-1){perror("Fail to listen");goto err;}

*lfd=fd;
return 0;

err:
close(fd);return -1;
}

int main(void)
{
int lfd,cfd,len,n;
time_t staletime;
struct sockaddr_un un;
struct stat statbuf;
char buf[MAX];

if(init(&lfd,PATH)==-1)
exit(1);
printf("running……n");

while(1)
{
len=sizeof(struct sockaddr_un);
if((cfd=accept(lfd,(struct sockaddr *)&un,&len))==-1)
{perror("Fail to accept");exit(1);}

len-=offsetof(struct sockaddr_un,sun_path);
un.sun_path[len]='';

if(stat(un.sun_path,&statbuf)==-1){perror("Fail to get status");exit(1);}
if((statbuf.st_mode&(S_IRWXG|S_IRWXO))||(statbuf.st_mode&S_IRWXU)!=S_IRWXU)
{printf("wrong permissionsn");exit(1);}

staletime=time(NULL)-STALE;
if(statbuf.st_atime<staletime||statbuf.st_ctime<staletime||statbuf.st_mtime<staletime){printf("client is too oldn");close(cfd);break;}

if(unlink(un.sun_path)==-1){perror("Fail to unlink");exit(1);}

n=read(cfd,buf,MAX);
if (n==-1)
{
perror("Fail to read");
exit(1);
}
else if(n==0)
{
printf("the connect closedn");
close(cfd);
continue;
}

if(strcmp(buf,"Nothing")==0)
goto close;

my_turn(buf);
if(write(cfd,buf,n)==-1){perror("Fail to write");exit(1);}
close(cfd);

}

if(unlink(PATH)==-1){perror("Fail to unlink");exit(1);}

close(lfd);
return 0;

close:
write(cfd,"Server Close",13);
close(cfd);
close(lfd);
if(unlink(PATH)==-1){perror("Fail to unlink");exit(1);}
return -1;
}

客户端

[ssj@main test]$ cat AFunixclient.c
#include <stdio.h>
#include <stddef.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>

#define PATH "/home/ssj/source/test/connect.socket"
#define C_PATH "/home/ssj/source/test/"
#define MAX 1024

int main(int argc,char *argv[])
{
int cfd,len;
struct sockaddr_un un;
char buf[MAX],*str="Nothing";
if(argc>1)
str=argv[1];

if((cfd=socket(AF_UNIX,SOCK_STREAM,0))==-1)
{perror("Fail to socket");exit(1);}

memset(&un,0,sizeof(struct sockaddr_un));
un.sun_family=AF_UNIX;
sprintf(un.sun_path,"%s%d",C_PATH,getpid());
len=offsetof(struct sockaddr_un,sun_path)+strlen(un.sun_path);

unlink(un.sun_path);

if(bind(cfd,(struct sockaddr *)&un,len)==-1)
{perror("Fail to bind");exit(1);}

if(chmod(un.sun_path,S_IRWXU)<0){perror("Fail to chmod");exit(1);}

memset(&un,0,sizeof(struct sockaddr_un));
un.sun_family=AF_UNIX;
strcpy(un.sun_path,PATH);

len=offsetof(struct sockaddr_un,sun_path)+strlen(un.sun_path);

if(connect(cfd,(struct sockaddr *)&un,len)<0)
{perror("Fail to connect");exit(1);}

if(write(cfd,str,len)==-1){perror("Fail to write");exit(1);}

if(read(cfd,buf,MAX)==-1){perror("Fail to read");exit(1);}

printf("recive from server:%sn",buf);
close(cfd);
return 0;
}

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注