现在的位置: 首页 > 综合 > 正文

UNP函数笔记三: TCP客户/服务器程序示例

2013年11月25日 ⁄ 综合 ⁄ 共 9080字 ⁄ 字号 评论关闭

第五章  TCP客户/服务器程序示例:

#include <sys/wait.h>
pid_t wait(int * statloc);
pid_t waitpid(pid_t pid, int * statloc, int options);
    pid:
        == -1, wait any child
        > 0,   wait child which child-gid == gid
        == 0,  wait any-child which child-group-id == parent-group-id
        < -1,  wait any-child which child-group-id == abs(pid)
    options:
        WCONTINUED, WNOHANG, WUNTRACED
    macros of check statloc:
        WIFEXITED(status)   --> WEXITSTATUS(status)
        WIFSIGNALED(status) --> WTERMSIG(status),  WCOREDUMP(status)
        WIFSTOPPED(status)  --> WSTOPSIG(status)
        WIFCONTINUED(status)
    if statloc is NULL means we neednot child's exit-status
    error return 0 or -1

示例:

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include "str_cli.h"

#define SERV_PORT 34567

int
main(int argc, char * argv[])
{
    int                 sockfd;
    struct sockaddr_in  servaddr;

    if (argc != 2) {
        printf("usage: %s <IPaddress>\n", argv[0]);
        exit(1);
    }

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        printf("socket error: %s\n", strerror(errno));
        exit(1);
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
        printf("inet_pton error: %s\n", strerror(errno));
        exit(1);
    }

    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
        printf("connect error: %s\n", strerror(errno));
        exit(1);
    }

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

    exit(0);
}

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include "str_echo.h"

#define LISTENQ   5
#define SERV_PORT 34567

int
main(int argc, char * argv[])
{
    int                 listenfd;
    int                 connfd;
    pid_t               childpid;
    socklen_t           clilen;
    struct sockaddr_in  cliaddr;
    struct sockaddr_in  servaddr;

    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        printf("socket error: %s\n", strerror(errno));
        exit(1);
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port        = htons(SERV_PORT);

    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
        printf("bind error: %s\n", strerror(errno));
        exit(1);
    }

    if ((listen(listenfd, LISTENQ)) == -1) {
        printf("listen error: %s\n", strerror(errno));
        exit(1);
    }

    for ( ; ; ) {
        clilen = sizeof(cliaddr);
        connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
        if (connfd == -1) {
            printf("accept error: %s\n", strerror(errno));
            exit(1);
        }

        if ((childpid = fork()) < 0) {
            printf("fork error: %s\n", strerror(errno));
            exit(1);
        }
        else if (childpid == 0) {
            if (close(listenfd) == -1) {
                printf("close listenfd error: %s\n", strerror(errno));
                exit(1);
            }
            str_echo(connfd);  /* process the request */
            exit(0);
        }
        else {
            if (close(connfd) == -1) {
                printf("close connfd error: %s\n", strerror(errno));
                exit(1);
            }
        }
    }
}

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

#include "myio.h"

#define MAXLINE 1024

void 
str_cli(FILE *fp, int sockfd)
{
    int   n;
    char  sendline[MAXLINE];
    char  recvline[MAXLINE];

    while (fgets(sendline, MAXLINE, fp) != NULL) {
        n = strlen(sendline);
        if (writen(sockfd, sendline, n) != n) {
            printf("writen error: %s\n", strerror(errno));
            exit(1);
        }

        if ((n = readline(sockfd, recvline, MAXLINE)) < 0) {
            printf("readline error: %s\n", strerror(errno));
            exit(1);
        }
        else if (n == 0) {
            printf("str_cli: server terminated prematurely\n");
            exit(0);
        }

        if (fputs(recvline, stdout) == EOF) {
            printf("fputs error: %s\n", strerror(errno));
            exit(1);
        }
    }
    if (ferror(fp)) {
        printf("fget error: %s\n", strerror(errno));
        exit(1);
    }
}

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

#include "myio.h"

#define MAXLINE 1024

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

again:
    while ((n = read(sockfd, buf, MAXLINE)) > 0) {
        if (writen(sockfd, buf, n) != n) {
            printf("writen error: %s\n", strerror(errno));
            exit(1);
        }
    }

    if (n < 0) {
        if (errno == EINTR) {
            goto again;
        }
        else {
            printf("str_echo: read error: %s\n", strerror(errno));
            exit(0);
        }
    }
}

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include "str_cli.h"

#define SERV_PORT 34567

int 
main(int argc, char * argv[])
{
    int                 i;
    int                 sockfd[5];
    struct sockaddr_in  servaddr;

    if (argc != 2) {
        printf("usage: %s <IPaddress>\n", argv[0]);
        exit(1);
    }

    for (i = 0; i < 5; ++i) {
        if ((sockfd[i] = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
            printf("socket error: %s\n", strerror(errno));
            exit(1);
        }

        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = htons(SERV_PORT);
        if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
            printf("inet_pton error: %s\n", strerror(errno));
            exit(1);
        }

        if (connect(sockfd[i], (struct sockaddr *)&servaddr, 
                    sizeof(servaddr)) == -1) {
            printf("connect error: %s\n", strerror(errno));
            exit(1);
        }
    }

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

    exit(0);
}

#include <stdio.h>
#include <errno.h>
#include <signal.h>

typedef void Sigfunc(int);

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

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

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include "str_echo.h"
#include "my_signal.h"

#define LISTENQ   5
#define SERV_PORT 34567

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

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

int 
main(int argc, char * argv[])
{
    int                 listenfd;
    int                 connfd;
    pid_t               childpid;
    socklen_t           clilen;
    struct sockaddr_in  cliaddr;
    struct sockaddr_in  servaddr;

    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        printf("socket error: %s\n", strerror(errno));
        exit(1);
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port        = htons(SERV_PORT);

    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
        printf("bind error: %s\n", strerror(errno));
        exit(1);
    }

    if ((listen(listenfd, LISTENQ)) == -1) {
        printf("listen error: %s\n", strerror(errno));
        exit(1);
    }

    if (my_signal(SIGCHLD, sig_chld) == SIG_ERR) { /* must call waitpid() */
        printf("my_signal error: %s\n", strerror(errno));
        exit(1);
    }

    for ( ; ; ) {
        clilen = sizeof(cliaddr);
        connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen);
        if (connfd < 0) {
            if (errno == EINTR) {
                continue;  /* back to for */
            }
            else {
                printf("accept error: %s\n", strerror(errno));
                exit(1);
            }
        }

        if ((childpid = fork()) < 0) {
            printf("fork error: %s\n", strerror(errno));
            exit(1);
        }
        else if (childpid == 0) {
            if (close(listenfd) == -1) {
                printf("close listenfd error: %s\n", strerror(errno));
                exit(1);
            }
            str_echo(connfd);  /* process the request */
            exit(0);
        }
        else {
            if (close(connfd) == -1) {
                printf("close connfd error: %s\n", strerror(errno));
                exit(1);
            }
        }
    }
}

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

#include "myio.h"

void
str_echo(int sockfd)
{
    long     arg1;
    long     arg2;
    ssize_t  n;
    char     line[MAXLINE];

    for ( ; ; ) {
        if ((n = readline(sockfd, line, MAXLINE)) < 0) {
            printf("readline error: %s\n", strerror(errno));
            exit(1);
        }
        else if (n == 0) {
            return;  /* connection closed by other end */
        }

        if (sscanf(line, "%ld%ld", &arg1, &arg2) == 2) {
            snprintf(line, sizeof(line), "%ld\n", arg1 + arg2);
        }
        else {
            snprintf(line, sizeof(line), "input error\n");
        }

        n = strlen(line);
        if (writen(sockfd, line, n) != n) {
            printf("writen error: %s\n", strerror(errno));
            exit(1);
        }
    }
}

struct args {
    long  arg1;
    long  arg2;
};

struct result {
    long  sum;
};

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

#include "sum.h"
#include "myio.h"

#define MAXLINE 1024

void 
str_cli(FILE * fp, int sockfd)
{
    int            n;
    char           sendline[MAXLINE];
    struct args    arg;
    struct result  ret;

    while (fgets(sendline, MAXLINE, fp) != NULL) {
        if (sscanf(sendline, "%ld%ld", &arg.arg1, &arg.arg2) != 2) {
            printf("invalid input: %s", sendline);
            continue;
        }

        if (writen(sockfd, &arg, sizeof(arg)) != sizeof(arg)) {
            printf("writen error: %s\n", strerror(errno));
            exit(1);
        }

        if ((n = readn(sockfd, &ret, sizeof(ret))) == 0) {
            printf("str_cli: server terminated prematurely");
            exit(0);
        }
        else if (n != sizeof(ret)) {
            printf("cli %d/%d readn error: %s\n", n, sizeof(ret), strerror(errno));
            exit(1);
        }
        else {
            printf("%ld\n", ret.sum);
        }
    }
}

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>

#include "sum.h"
#include "myio.h"

void 
str_echo(int sockfd)
{
    ssize_t        n;
    struct args    arg;
    struct result  ret;

    for ( ; ; ) {
        if ((n = readn(sockfd, &arg, sizeof(arg))) == 0) {
            return;  /* connection closed by other end */
        }
        else if (n != sizeof(arg)) {
            printf("readn error: %s\n", strerror(errno));
            exit(1);
        }

        ret.sum = arg.arg1 + arg.arg2;
        if (writen(sockfd, &ret, sizeof(ret)) != sizeof(ret)) {
            printf("writen error: %s\n", strerror(errno));
            exit(1);
        }
    }
}

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include "my_signal.h"

#define SERV_PORT 34567

void 
sig_pipe(int signo)
{
    printf("SIGPIPE received\n");
    return;
}

int 
main(int argc, char * argv[])
{
    int                 sockfd;
    struct sockaddr_in  servaddr;

    if (argc != 2) {
        printf("usage: %s <IPaddress>\n", argv[0]);
        exit(1);
    }

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        printf("socket error: %s\n", strerror(errno));
        exit(1);
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
        printf("inet_pton error: %s\n", strerror(errno));
        exit(1);
    }

    if (my_signal(SIGPIPE, sig_pipe) == SIG_ERR) { /* must call waitpid() */
        printf("my_signal error: %s\n", strerror(errno));
        exit(1);
    }

    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
        printf("connect error: %s\n", strerror(errno));
        exit(1);
    }

    sleep(2);

    if (write(sockfd, "hello", 5) != 5) {
        printf("write 1 error: %s\n", strerror(errno));
        exit(1);
    }

    sleep(2);

    if (write(sockfd, "world", 5) != 5) {
        printf("write 2 error: %s\n", strerror(errno));
        exit(1);
    }

    exit(0);
}

抱歉!评论已关闭.