UNIX domain sockets are used to communicate between processes running on the same machine. UNIX domain sockets provide both stream and datagram interfaces. Create a pair of non-named, interconnected UNIX domain sockets. Socketpair
1. Naming unix domain sockets1) Socket address format, under Linux as shown in struct Sockaddr_un {sa_family_t sun_family; char sun_path[108];} Bind this address:
#include <stdlib.h>#include<string.h>#include<sys/socket.h>#include<stdio.h>#include<sys/un.h>#include<errno.h>intMainvoid){ intfd,size; structsockaddr_un un; Un.sun_family= Af_unix;//UNIX Domainstrcpy (Un.sun_path,"Foo.socket"); if(Fd=socket (Af_unix, Sock_stream,0)) <0) {printf ("Socket failed\n"); Exit (-1); } size=sizeof(structSockaddr_un); if(Bind (FD, (structSOCKADDR *) &un, size) <0) {printf ("bind failed:[%s]\n", Strerror (errno)); Exit (-1); } printf ("UNIX domain Socket bound\n"); Exit (0);}
# ls-l
Srwxr-xr-x 1 dev_old_run swdev 0 Sep 7 13:49 foo.socket The first bit represents the file type, which is a socket file
2. Unique Connection1) The Serv_listen function uses bind, listen, and accept2) serv_accept function Accept to verify that the identity of the client process is the owner of the socket: Verify that the path name is a socket, that permissions allow only user-read, user-write, and user-execute, The 3 time associated with a socket is no more than 30 seconds earlier than the current time. Verify the identity of this piece, I understand here is the server to the path of the judgment, as long as the right to determine the permissions, the client can basically identify the identity.
#include <sys/socket.h>#include<sys/un.h>#include<unistd.h>#include<string.h>#include<errno.h>#include<sys/stat.h>#include<time.h>#include<stddef.h>#defineQlen 10#defineSTALE 30intMainvoid){}//Create service side, return FD successfully, error return value <0intServ_listen (Const Char*name) { intFd,err,rval, Len; structsockaddr_un un; if(FD = socket (Af_unix, Sock_stream,0)) <0) return-1; unlink (name); //file exists, first disassociate//populating the socket address structurememset (&un,0,sizeof(un)); Un.sun_family=Af_unix; strcpy (Un.sun_path, name); //bind address to descriptor if(Bind (FD, (structSOCKADDR *) &un, Len) <0) {Rval= -2; Gotoerrout; } if(Listen (FD, Qlen) <0) {Rval= -3; Gotoerrout; } return(FD); Errout:err=errno; Close (FD); errno=err; return(Rval);}//wait for the customer to connect and accept it//verify the identity of the customer at the same timeintServ_accept (intLISTENFD, uid_t *uidptr) { intclifd, Rval, err; Socklen_t Len; structsockaddr_un un; structstat statbuf; time_t Staletime; Len=sizeof(un); if(Clifd = Accept (LISTENFD, (structSOCKADDR *) &un, &len) <0) return-1; //determine the identity of the client process is the owner of the socketLen-= Offsetof (structSockaddr_un, Sun_path);//Path Lengthun.sun_path[len]=0;//increase the/end character if(Stat (Un.sun_path, &statbuf) <0) {Rval= -2; Gotoerrout; } //file type checking if(S_issock (statbuf.st_mode) = =0) {Rval= -3; Gotoerrout; } //file Permission Check if(Statbuf.st_mode & (S_irwxg | S_IRWXO)) | |Statbuf.st_mode& S_irwxu! =S_irwxu) {Rval= -4; Gotoerrout; } staletime= Time (NULL)-STALE; if(Statbuf.st_atime < Staletime | |Statbuf.st_ctime< Staletime | |Statbuf.st_mtime<staletime) {Rval= -5; Gotoerrout; } if(Uidptr! =NULL)*uidptr = Statbuf.st_uid;//return UIDunlink (Un.sun_path); return(CLIFD); Errout:err=errno; Close (CLIFD); errno=err; returnRval;}
3) The Cli_conn function client binds a path name and sets its permissions. This allows the server to verify the identity of the client process in Serv_accept by verifying these permissions. Then populate the server's SOCKADDR_UN structure, calling connect to connect to the server.
#include <stdlib.h>#include<sys/socket.h>#include<sys/un.h>#include<unistd.h>#include<errno.h>#include<sys/stat.h>#include<string.h>#include<sys/un.h>#include<stddef.h>#defineCli_path "/var/tmp/"#defineCli_perm S_irwxuintMainvoid) {exit (0);}intCli_conn (Const Char*name) { intFD, Len, err, rval; structsockaddr_un un; if(FD = socket (Af_unix, Sock_stream,0)) <0) return-1; //Populate client Addressmemset (&un,0,sizeof(un)); Un.sun_family=Af_unix; sprintf (Un.sun_path,"%s%05d", Cli_path, Getpid ()); Len= Offsetof (structSockaddr_un, Sun_path) +strlen (Un.sun_path); Unlink (Un.sun_path); //binding to Sockets if(Bind (FD, (structSOCKADDR *) &un, Len) <0) {Rval= -2; Gotoerrout; } if(Chmod (Un.sun_path, Cli_perm) <0) {Rval= -3; Gotoerrout; } //populating server-side addressesmemset (&un,0,sizeof(un)); Un.sun_family=Af_unix; strcpy (Un.sun_path, name); Len= Offsetof (structSockaddr_un, Sun_path) +strlen (Un.sun_path); if(Connect (FD, (structSOCKADDR *) &un, Len) <0) {Rval= -4; Gotoerrout; } return(FD); Errout:err=errno; Close (FD); errno=err; return(Rval);}
UNIX domain sockets (Unix domains)