网络编程学习笔记(SIGPIPE信号触发)

来源:互联网 发布:quickfix java 编辑:程序博客网 时间:2024/06/05 06:09
服务端代码:
#include <sys/socket.h>#include <stdio.h>#include <netinet/in.h>#include <arpa/inet.h>#include <errno.h>#include <string.h>#include <time.h>#include <unistd.h>#include <stdlib.h>#include <sys/wait.h>#define SIN_PORT 9999#define BUFLEN 256void str_echo(int fd);void sig_child(int signo){    pid_t pid;    int stat;    while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {        printf("pid %d terminated\n", pid);    }}int main(int argc, char **argv){    int listenfd, connfd;    pid_t child;    struct sockaddr_in servaddr;    char buf[BUFLEN];    time_t ticks;    listenfd = socket(AF_INET, SOCK_STREAM, 0);    if (listenfd < 0) {        printf("socket error :%s\n", strerror(errno));                return -1;    }    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(SIN_PORT);    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);    signal(SIGCHLD, sig_child);        if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {        printf("bind error:%s\n", strerror(errno));        close(listenfd);        return -1;    }            if (listen(listenfd, 3) < 0) {        printf("listen error:%s\n", strerror(errno));        close(listenfd);        return -1;    }            struct sockaddr_in clientaddr;    int len;    for (;;) {        len = sizeof(clientaddr);        connfd = accept(listenfd, (struct sockaddr*)&clientaddr, &len);        if (connfd < 0) {            printf("accept error:%s\n", strerror(errno));            close(listenfd);            return -1;        }        if ((child = fork()) == 0) {            close(listenfd);            str_echo(connfd);              return 0;        }                /*        printf("connection from %s, port:%d\n", inet_ntop(AF_INET, &clientaddr.sin_addr, buf, sizeof(buf)), htons(clientaddr.sin_port));        ticks = time(NULL);        snprintf(buf, sizeof(buf), "%.24s\r\n", ctime(&ticks));        write(connfd, buf, strlen(buf));        */        close(connfd);            }    return 0;}size_t readn(int fd, void *ptr, size_t n){    char *p = ptr;    size_t nleft = n;    size_t nread;    while (nleft > 0) {        if ((nread = read(fd, p, nleft)) < 0) {            if (errno == EINTR) nread = 0;            else return -1;        } else if (nread == 0) break;        nleft -= nread;        p += nread;    }    return n - nleft;}size_t readline(int fd, void *ptr, size_t maxsize){    char *p = ptr;    size_t rc, n;    char c;    for (n = 1; n < maxsize; n++) {again:        if ((rc = read(fd, &c, 1)) == 1) {            *p++ = c;            if (c == '\n') break;            } else if (rc == 0) {                if (n == 1) return 0;                else break;        } else {            if (errno == EINTR) goto again;            return -1;        }    }    *p = 0;    return n;}size_t writen(int fd, void *ptr, size_t n){    char *p = ptr;    size_t nleft = n,  nwriten;    while (nleft > 0) {        if ((nwriten = write(fd, p, nleft)) <= 0) {            if (errno == EINTR) nwriten = 0;            else return -1;        }        p += nwriten;        nleft -= nwriten;    }    return n;}void str_echo(int fd){    char recvline[BUFLEN];    int n;        for (;;) {        if ((n = readline(fd, recvline, BUFLEN)) == 0) return;         printf("received buf=%s", recvline);        writen(fd, recvline, n);    }}

客户端代码:

#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdio.h>#include <errno.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <stdio.h>#define SIN_PORT 9999#define BUF_LEN 256#define max(a, b) ((a) > (b) ? (a) : (b))size_t readline(int fd, void *ptr, int maxsize){    char *p = ptr;    char c;    int rc;    int n;        for (n = 1; n < maxsize; n++) {    again:        if ((rc = read(fd, &c, 1)) == 1) {              *p++ = c;              if (c == '\n') break;         } else if (rc == 0) {                    if (n == 1) return 0;                       else break;                       }else {            if (errno == EINTR) goto again;            else return -1;        }    }        *p = 0;    return n;}size_t readn(int fd, void *ptr, size_t n){    char *p = ptr;    int nleft = n;    int nread;        while (nleft > 0) {          if ((nread = read(fd, p, nleft)) < 0) {                if (errno == EINTR) nread = 0;                else return -1;          } else if (nread == 0) break;          nleft -= nread;          p += nread;    }        return n - nleft;}size_t writen(int fd, void *ptr, size_t n){    size_t nwriten;    size_t nleft = n;    char *p = ptr;        while (nleft > 0) {          if ((nwriten = write(fd, p, nleft)) <= 0) {                if (errno == EINTR) nwriten = 0;                else return -1;          }                    nleft -= nwriten;          p += nwriten;    }        return n;}void str_cli(FILE *file, int fd){    char recvline[BUF_LEN], sendline[BUF_LEN];    int maxfdp1;    /*    fd_set fdset;    int ret;    FD_ZERO(&fdset);    for(;;) {        FD_SET(fileno(file), &fdset);        FD_SET(fd, &fdset);        maxfdp1 = max(fileno(file), fd) + 1;        ret = select(maxfdp1, &fdset, NULL, NULL, NULL);           if (ret <= 0) {             continue;        }        //printf("ret=%d\n", ret);        if (FD_ISSET(fd, &fdset)) {            if (readline(fd, recvline, BUF_LEN) == 0) {                printf("readline error:%s\n", strerror(errno));                return;            }            fputs(recvline, stdout);        }             if (FD_ISSET(fileno(file), &fdset)) {            memset(sendline, 0x00, sizeof(sendline));            if (fgets(sendline, BUF_LEN, file) == NULL) {                printf("fgets error:%s\n", strerror(errno));                return;            }                        //printf("len=%d\n", strlen(sendline));            writen(fd, sendline, strlen(sendline));        }       }    */   while (fgets(sendline, BUF_LEN, file) != NULL) {writen(fd, sendline, 1);sleep(1);writen(fd, sendline, strlen(sendline) - 1);if (readline(fd, recvline, BUF_LEN) == 0) {printf("readline error:%s\n", strerror(errno));return;}fputs(recvline, stdout);   }}int main(int argc, char** argv){    struct sockaddr_in serveraddr;    int sockfd;    #ifndef ONLINE_JUDGE    //freopen("6.4Client.c", "r", stdin);#endif    sockfd = socket(AF_INET, SOCK_STREAM, 0);    if (sockfd < 0) {        printf("socket error:%s\n", strerror(errno));        return -1;    }           serveraddr.sin_family = AF_INET;    serveraddr.sin_port = htons(SIN_PORT);    if (inet_pton(AF_INET, argv[1], &serveraddr.sin_addr) != 1) {          printf("inet_pton error:%s\n", strerror(errno));          close(sockfd);          return -1;    }        if (connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0) {        printf("connect error:%s\n", strerror(errno));        close(sockfd);        return -1;    }        str_cli(stdin, sockfd);        exit(0);    }

当进程向一个接收了RST的套接口执行写操作时,会触发SIGPIPE信号,此信号的默认行为是终止进程

终止服务端子进程,在客户端输入字符串,客户端先向服务端发送一个字符,些时客户端收到RST,再向该套接口发送字符,些时会触发SIGPIPE信号 

用echo $?查看程序输出结果,输出为141,SIGPIPE的信号值为13,即128 + 13

0 0
原创粉丝点击