unix域字节流回射程序

一、服务端程序

#include    <stdio.h>
#include    <errno.h>
#include    <stdlib.h>
#include    <unistd.h>
#include    <signal.h>
#include    <string.h>
#include    <sys/un.h>
#include    <sys/socket.h>
#include    <sys/wait.h>

#define     SA              struct sockaddr
#define     UNIXSTR_PATH    "/tmp/unix.str"
#define     LISTENQ         1024
#define     MAXLINE         4096

typedef     void            Sigfunc(int);

Sigfunc     *signal(int, Sigfunc *);
void        err_sys(const char *, ...);
void        str_echo(int);
ssize_t     writen(int, const void *, size_t);

int main(int argc, char **argv)
{
    int                  listenfd, connfd;
    pid_t                childpid;
    socklen_t            clilen;
    struct sockaddr_un   cliaddr, servaddr;
    void                 sig_chld(int);

    listenfd = socket(AF_LOCAL, SOCK_STREAM, 0);

    unlink(UNIXSTR_PATH);
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sun_family = AF_LOCAL;
    strcpy(servaddr.sun_path, UNIXSTR_PATH);

    bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

    listen(listenfd, LISTENQ);

    signal(SIGCHLD, sig_chld);

    for ( ; ; ) {
        clilen = sizeof(cliaddr);
        if ( (connfd = accept(listenfd, (SA *) &cliaddr, &clilen)) < 0) {
            if (errno == EINTR) {
                continue;                /* back to for() */
            }
            else {
                err_sys("accept error");
            }
        }

        if ( (childpid = fork()) == 0) { /* child process */
            close(listenfd);             /* close listening socket */
            str_echo(connfd);            /* process request */
            exit(0);
        }
        close(connfd);                   /* parent closes connected socket */
    }
}

Sigfunc *signal(int signo, Sigfunc *func) {
    struct sigaction act, oact;

    act.sa_handler = func;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    if (signo != SIGALRM) {
    act.sa_flags |= SA_RESTART;
    }
    if (sigaction(signo, &act, &oact) < 0) {
    return SIG_ERR;
    }
    return (oact.sa_handler);
}

void sig_chld(int signo) {
    pid_t pid;
    int stat;

    while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0) {
        printf("child %d terminated
", pid);
    }
    return;
}

void str_echo(int sockfd) {
    ssize_t n;
    char buf[MAXLINE];

    again:
    while ( (n = read(sockfd, buf, MAXLINE)) > 0) {
        writen(sockfd, buf, n);
        bzero(buf, sizeof(buf));
    }
    if (n < 0 && errno == EINTR) {
        goto again;
    } else if (n < 0) {
        perror("read");
    }
}

ssize_t writen(int fd, const void *vptr, size_t n) {
    size_t nleft;
    ssize_t nwriten;
    const char *ptr;

    ptr = vptr;
    nleft = n;
    while (nleft > 0) {
        if ( (nwriten = write(fd, ptr, nleft)) <= 0) {
            if (nwriten < 0 && errno) {
                nwriten = 0; /* call write() again */
            } else {
                return (-1); /* error */
            }
        }
        nleft -= nwriten;
        ptr += nwriten;
    }
    return (n - nwriten);
}
#include    <stdio.h>
#include    <errno.h>
#include    <stdlib.h>
#include    <string.h>
#include    <stdarg.h>         /* ANSI C header file */
#include    <syslog.h>         /* for syslog() */

#define     MAXLINE     4096

int        daemon_proc;        /* set nonzero by daemon_init() */

static void    err_doit(int, int, const char *, va_list);

/* Nonfatal error related to system call
 * Print message and return */

void err_ret(const char *fmt, ...) {

    va_list        ap;    

    va_start(ap, fmt);    
    err_doit(1, LOG_INFO, fmt, ap);
    va_end(ap);
    return;
}

/* Fatal error related to system call
 * Print message and terminate */

void err_sys(const char *fmt, ...) {

    va_list        ap;

    va_start(ap, fmt);
    err_doit(1, LOG_ERR, fmt, ap);
    va_end(ap);
    exit(1);
}

/* Fatal error related to system call
 * Print message, dump core, and terminate */

void err_dump(const char *fmt, ...) {
    va_list        ap;

    va_start(ap, fmt);
    err_doit(1, LOG_ERR, fmt, ap);
    va_end(ap);
    abort();        /* dump core and terminate */
    exit(1);        /* shouldn't get here */
}

/* Nonfatal error unrelated to system call
 * Print message and return */

void err_msg(const char *fmt, ...) {

    va_list        ap;

    va_start(ap, fmt);
    err_doit(0, LOG_INFO, fmt, ap);
    va_end(ap);
    return;
}

/* Fatal error unrelated to system call
 * Print message and terminate */

void err_quit(const char *fmt, ...) {

    va_list        ap;

    va_start(ap, fmt);
    err_doit(0, LOG_ERR, fmt, ap);
    va_end(ap);
    exit(1);
}

/* Print message and return to caller
 * Caller specifies "errnoflag" and "level" */

static void err_doit(int errnoflag, int level, const char *fmt, va_list ap) {

    int        errno_save, n;
    char    buf[MAXLINE + 1];

    errno_save = errno;                /* value caller might want printed */
#ifdef    HAVE_VSNPRINTF
    vsnprintf(buf, MAXLINE, fmt, ap);  /* safe */
#else
    vsprintf(buf, fmt, ap);            /* not safe */
#endif
    n = strlen(buf);
    if (errnoflag)
        snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
    strcat(buf, "
");

    if (daemon_proc) {
        syslog(level, buf, NULL);
    } else {
        fflush(stdout);                /* in case stdout and stderr are the same */
        fputs(buf, stderr);
        fflush(stderr);
    }
    return;
}

二、客户端程序

#include    <stdio.h>
#include    <errno.h>
#include    <stdlib.h>
#include    <unistd.h>
#include    <string.h>
#include    <sys/socket.h>
#include    <sys/un.h>

#define     SA              struct sockaddr
#define     UNIXSTR_PATH    "/tmp/unix.str"
#define     MAXLINE         4096

void        str_cli(FILE *, int);
ssize_t     writen(int, const void *, size_t);

int main(int argc, char **argv)
{
    int                   sockfd;
    struct sockaddr_un    servaddr;

    socket:
    if ( (sockfd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) {
        if (errno == EINTR) {
            goto socket;
        } else {
            perror("socket");
            exit(-1);
        }
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sun_family = AF_LOCAL;
    strcpy(servaddr.sun_path, UNIXSTR_PATH);

    connect:
    if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) {
        if (errno == EINTR) {
            goto connect;
        } else {
            perror("connect");
            exit(-1);
        }
    }

    str_cli(stdin, sockfd);        /* do it all */

    exit(0);
}

void str_cli(FILE *fp, int sockfd) {

    char sendline[MAXLINE], recvline[MAXLINE];

    while(fgets(sendline, MAXLINE, fp) != NULL) {
        writen(sockfd, sendline, strlen(sendline));

        if (read(sockfd, recvline, MAXLINE) < 0) {
            return;
        }
        fputs(recvline, stdout);
        bzero(recvline, sizeof(recvline));
    }
}

ssize_t writen(int fd, const void *vptr, size_t n) {
    size_t nleft;
    ssize_t nwritten;
    const char *ptr;

    ptr = vptr;
    nleft = n;
    while (nleft > 0) {
        if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
            if (nwritten < 0 && errno == EINTR) {
                nwritten = 0; /* call write() again */
            } else {
                return (-1); /* error */
            }
        }
        nleft -= nwritten;
        ptr   += nwritten;
    }
    return (n - nwritten);
}
原文地址:https://www.cnblogs.com/soldierback/p/10765369.html