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 }