Unix Domain Socket的例子

下面是unix domain socket的服务器端和客户端的两个代码。

和internet的socket区别有

1. 使用AF_UNIX 而不是AF_INET

2. unix domain socket在bind时会生成一个文件,而AF_INET不会。

   所以需要手动删除,否则不能bind成功。

 

/*
 * =====================================================================================
 *
 *       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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值