SIGPIPE信号

 1 #include <sys/types.h>
 2 #include <sys/socket.h>
 3 #include <netinet/in.h>
 4 #include <arpa/inet.h>
 5 #include <unistd.h>
 6 #include <errno.h>
 7 #include <signal.h>
 8 
 9 #include <string.h>
10 #include <assert.h>
11 #include <iostream>
12 
13 void signal_func(int sig)
14 {
15     int saved_errno = errno;
16     std::cout << "broken pipe!" << std::endl;
17     errno = saved_errno;
18 }
19 
20 int main()
21 {
22     struct sigaction sa;
23     sa.sa_handler = signal_func;
24 
25     sigemptyset(&sa.sa_mask);
26     sa.sa_flags = 0;
27 
28     if (sigaction(SIGPIPE, &sa, NULL) < 0)
29     {
30         perror("cannot ignore SIGPIPE");
31 
32         return -1;
33     }
34 
35     int sockfd = socket(AF_INET, SOCK_STREAM, 0);
36     uint16_t port = 7888;
37     const char* ip= "192.168.16.105";
38 
39     assert(sockfd > 0);
40 
41     struct sockaddr_in sock_address;
42     memset(&sock_address, 0, sizeof(sock_address));
43 
44     sock_address.sin_family = AF_INET;
45     sock_address.sin_port = htons(7888);
46     inet_pton(AF_INET, ip, &(sock_address.sin_addr));
47 
48     socklen_t sock_len = sizeof(sock_address);
49 
50     int ret = connect(sockfd, (sockaddr*)&sock_address, sock_len);
51     assert(ret != -1);
52 
53     sleep(10); // 在sleep之前断开服务端连接
54 
55     char send_buff[1024] = "hello server!";
56     char recv_buff[1024] = {0};
57 
58     ssize_t ret_1 = send(sockfd, send_buff, strlen(send_buff), 0); // 收到对端FIN后依然可以发送成功 不过对端会响应RST
59 
60     if (ret_1 < 0)
61     {
62         std::cout << strerror(errno) << std::endl;
63     }
64     else
65     {
66         std::cout << "send success!" << std::endl;
67     }
68 
69     ssize_t ret_2 = recv(sockfd, recv_buff, sizeof(recv_buff), 0);
70 
71     if(ret_2 == 0)
72     {
73         std::cout << "remote close connection" << std::endl;
74     }
75 
76     ssize_t ret_3 = send(sockfd, send_buff, strlen(send_buff), 0); // 这时再send会出错 并产生SIGPIPE信号 默认终止进程
77 
78     if(ret_3 < 0)
79     {
80         if (errno == EPIPE)
81         {
82             std::cout << strerror(errno) << std::endl;
83         }
84     }
85     else
86     {
87         std::cout << "send success" << std::endl;
88     }
89 
90     return 0;
91 }

 

posted @ 2016-08-06 15:54  Ricardo  阅读(322)  评论(0编辑  收藏  举报