Here are the two code for the server side and client of the UNIX domain socket.
There is a difference between the socket and the Internet
1. Use Af_unix instead of af_inet
2. Unix domain sockets generate a file when bind, and Af_inet does not.
So it needs to be removed manually, otherwise it cannot bind successfully.
/*
* =====================================================================================
*
* FILENAME:UNIX_SOCKET_SERV.C
*
* Description:
*
* version:1.0
* created:09/09/2010 08:26:42 PM
* Revision:none
* COMPILER:GCC
*
* Author:your NAME (),
* Company:
*
* =====================================================================================
*/
#include <apue.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <time.h>
#define Qlen 10
#define STALE 30
Int
SERV_LISTEN1 (const char *name)
{
int FD, Len, err, rval;
struct Sockaddr_un un;
if (FD = socket (Af_unix, sock_stream, 0)) < 0)
return-1;
unlink (name); /* In case it already exists */
memset (&un, 0, sizeof (un));
un.sun_family = Af_unix;
strcpy (Un.sun_path, name);
Len = offsetof (struct Sockaddr_un, Sun_path) + strlen (name);
if (Bind (FD, (struct sockaddr *) &un, Len) < 0)
{
Rval =-2;
Goto Errout;
}
if (Listen (FD, Qlen) < 0)
{
Rval =-3;
Goto Errout;
}
return FD;
Errout:
err = errno;
Close (FD);
errno = err;
return rval;
}
Int
SERV_ACCEPT1 (int listenfd, uid_t *uidptr)
{
int CLIFD, Len, err, rval;
time_t Staletime;
struct Sockaddr_un un;
struct stat statbuf;
len = sizeof (un);
if (Clifd = Accept (LISTENFD, (struct sockaddr *) &un, &len)) < 0)
return-1;
Len-= offsetof (struct sockaddr_un, sun_path);
Un.sun_path[len] = 0;
if (stat (Un.sun_path, &statbuf) < 0)
{
Rval =-2;
Goto Errout;
}
#ifdef S_issock
if (S_issock (statbuf.st_mode) = = 0)
{
Rval =-3;
Goto Errout;
}
#endif
if (Statbuf.st_mode & (S_irwxg | S_IRWXO)) | |
(Statbuf.st_mode & s_irwxu)! = S_irwxu)
{
Rval =-4; /* is not rwx------*/
Goto Errout;
}
Staletime = Time (NULL)-STALE;
if (Statbuf.st_atime < Staletime | |
Statbuf.st_ctime < Staletime | |
Statbuf.st_mtime < Staletime)
{
Rval =-5; /* I-node is too old */
Goto Errout;
}
if (uidptr! = NULL)
*uidptr = Statbuf.st_uid;
Unlink (Un.sun_path);
return CLIFD;
Errout:
err = errno;
Close (CLIFD);
errno = err;
return rval;
}
Int
Main ()
{
int socket;
int conn;
uid_t uid;
Char buf[1024];
Socket = Serv_listen1 ("Unix_serv");
conn = SERV_ACCEPT1 (socket, &uid);
printf ("UID:%d/n", UID);
READ (conn, buf, 1024);
printf ("%s/n", buf);
return 0;
}
/*
* =====================================================================================
*
* FILENAME:UNIX_SOCKET_CLIENT.C
*
* Description:
*
* version:1.0
* created:09/09/2010 08:30:48 PM
* Revision:none
* COMPILER:GCC
*
* Author:your NAME (),
* Company:
*
* =====================================================================================
*/
#include <apue.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#define Cli_path "/var/tmp/"
#define CLI_PERM S_irwxu
Int
CLI_CONN1 (const char *name)
{
int FD, Len, err, rval;
struct Sockaddr_un un;
if (FD = socket (Af_unix, sock_stream, 0)) < 0)
return-1;
/* Fill socket address structure with out address */
memset (&un, 0, sizeof (un));
un.sun_family = Af_unix;
sprintf (Un.sun_path, "%s%05d", Cli_path, Getpid ());
Len = offsetof (struct Sockaddr_un, Sun_path) + strlen (Un.sun_path);
Unlink (Un.sun_path);
if (Bind (FD, (struct sockaddr *) &un, Len) < 0)
{
Rval =-2;
Goto Errout;
}
if (chmod (Un.sun_path, Cli_perm) < 0)
{
Rval =-3;
Goto Errout;
}
/* Fill SOCET address structure with server ' s address */
memset (&un, 0, sizeof (un));
un.sun_family = Af_unix;
strcpy (Un.sun_path, name);
Len = offsetof (struct Sockaddr_un, Sun_path) + strlen (Un.sun_path);
if (Connect (fd, (struct sockaddr *) &un, Len) < 0)
{
Rval =-4;
Goto Errout;
}
return FD;
Errout:
err = errno;
Close (FD);
errno = err;
return rval;
}
Int
Main ()
{
int FD;
FD = CLI_CONN1 ("Unix_serv");
if (FD < 0)
{
Err_quit ("Client error:");
}
Write (FD, "Test", 4);
return 0;
}