网络编程学习笔记(SIGPIPE信号触发)
来源:互联网 发布:quickfix java 编辑:程序博客网 时间:2024/06/05 06:09
服务端代码:
当进程向一个接收了RST的套接口执行写操作时,会触发SIGPIPE信号,此信号的默认行为是终止进程
#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
- 网络编程学习笔记(SIGPIPE信号触发)
- 网络编程(三) SIGPIPE信号
- 关于网络编程时候SIGPIPE信号
- 关于网络编程时候SIGPIPE信号
- 网络编程中的SIGPIPE信号以及close和shutdown
- socket编程中的SIGPIPE信号
- socket编程问题-SIGPIPE信号处理
- socket编程问题-SIGPIPE信号处理
- socket编程问题-SIGPIPE信号处理
- [iOS编程-XCode Debug忽略SIGPIPE信号
- socket编程中出现SIGPIPE信号
- [iOS编程-XCode Debug忽略SIGPIPE信号
- iOS编程-XCode Debug忽略SIGPIPE信号
- SIGPIPE信号
- SIGPIPE信号
- SIGPIPE信号
- SIGPIPE信号
- SIGPIPE信号
- div浮动排版
- WEB基本表单及代码(HTML)
- GUI编程第三弹_按钮上的ActionEvent事件
- nyoj-212-K尾相等数
- ieee80211_rx_h_mgmt的处理
- 网络编程学习笔记(SIGPIPE信号触发)
- mvc的运行原理
- 用packer + ansible定制Centos AMI
- [bash]for、while/until、循环控制、循环输出定向和管接
- java学习笔记3--参数的传递方式
- Django入门
- 黑马程序员——GUI
- hdu2074 模拟规律
- C语言变量和函数命名规范