uds server client sample

linux 2008. 7. 6. 23:19
server.c

/** Unix Domain Socket
 * Figure 17.15, 16 on p597 ~ p599 of APUE */

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <sys/stat.h>

#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>


#define QLEN    10
#define STALE    30
#define BUFLEN    128

int serv_listen(const char* name);
int serv_accept(int listenfd, uid_t *uidptr);
void serve(int sockfd);

int main(int argc, char* argv[])
{
    int sockfd, size;
    struct sockaddr_un un;

    //un.sun_family = AF_UNIX;
    //strcpy(un.sun_path, "foo.socket");
    //if ( (sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
    //{
        //printf("socket failed\n");
        //exit(1);
    //}
    //size = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
    //if ( bind(sockfd, (struct sockaddr*) &un, size) < 0)
    //{
        //printf("bind failed\n");
        //exit(1);
    //}
    if ( ( sockfd = serv_listen("./foo.socket") )  < 0 )
    {
        printf("listen failed\n");
        exit(1);
    }
    if ( sockfd >= 0 )
    {
        serve(sockfd);
        exit(0);
    }
    exit(1);
}

void
serve (int sockfd)
{
    int clfd;
    FILE    *fp;
    char    buf[BUFLEN];
   
    while (1)
    {
        uid_t temp;
        clfd = serv_accept(sockfd, &temp);
        if (clfd < 0)
        {
                    printf("runtimed:%d accept error: %s\n", clfd, strerror(errno));
            exit(1);
        }
        send(clfd, "ServerTalks", strlen("ServerTalks"), 0);
        close(clfd);
    }
}

int
serv_listen(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);

    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_accept(int listenfd, uid_t *uidptr)
{
    int    clifd, err, rval;
    socklen_t    len;
    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;
        goto errout;
    }

    staletime = time(NULL) - STALE;
    if (statbuf.st_atime < staletime ||
            statbuf.st_ctime < staletime ||
            statbuf.st_mtime < staletime )
    {
        rval = -5;
        goto errout;
    }

    if (uidptr != NULL)
        *uidptr = statbuf.st_uid;
    unlink(un.sun_path);
    return clifd;

errout:
    err = errno;
    close(clifd);
    errno = err;
    return rval;
}



/////////////////////////////////////



client.c


/** Unix Domain Socket
 * Figure 17.17 p600 Advanced Unix Programming Environment */

#include <stdio.h> //19
#include <stdlib.h>
#include <stddef.h>
#include <sys/stat.h>

#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>

#define CLI_PATH    "/var/tmp"
#define CLI_PERM    S_IRWXU
#define BUFLEN    128

int cli_conn(const char *name);

int
main(int argc, char* argv[])
{
//    struct addrinfo *ailist, *aip;
    int sockfd;

    //if ((sockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
    //{
        //printf("socket failed\n");
        //exit(1);
    //}
    if ((sockfd = cli_conn("./foo.socket")) < 0)
    {
        printf("connect failed\n");
        exit(1);
    }
    else
    {
        int n;
        char buf[BUFLEN];
        while( (n = recv(sockfd, buf, BUFLEN, 0)) > 0 )
        {
            write(1, buf, n);
            //printf("%s", buf);
        }
        if (n < 0)
        {
            printf("recv error\n");
            exit(1);
        }
        exit(0);
    }
    exit(1);
}
   
   
   

int
cli_conn(const char *name)
{
    int    fd, len, err, rval;
    struct    sockaddr_un    un;

    if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
        return -1;
    memset(&un, 0, sizeof(un));
    un.sun_family = AF_UNIX;
    strcpy(un.sun_path, "./fooclient.socket");
    //sprintf(un.sun_path, "%s", name);//foo.socket");//"%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;
    }
    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 (connect(fd, (struct sockaddr*)&un, len) < 0)
    {
        rval = -4;
        goto errout;
    }
    return fd;

errout:
    err = errno;
    close(fd);
    errno = err;
    return rval;
}







Posted by 언제나19
l