First enter the code:
//server void newConnection(int sockfd,const InetAddress &addr) { ::write(sockfd, "how are you?\n", 13); //简单地回复一句话 } int main() { EventLoop loop; InetAddress listenAddr(12345); Acceptor acceptor(&loop, listenAddr); acceptor.setConnectionCallback(newConnection); //listenfd可读(新连接)调用回调 acceptor.listen(); //Accept::listen调用listenfd的listen //while(true)循环,Acceptor构造时讲listenfd放进loop的epoll结构中, //本循环检测到listenfd可读(新连接)之后调用accept得到connfd,然后调用上面set的回调函数 loop.loop(); } //client int main(int argc, char **argv) { struct sockaddr_in addr; bzero(&addr, sizeof addr); addr.sin_family = AF_INET; addr.sin_port = htons(12345); inet_pton(AF_INET, argv[1], &addr.sin_addr); int sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); //连接server char buf[256] = {'rrreee'}; read(sockfd, buf, sizeof(buf)); //接受msg printf("Received: %s\n", buf); close(sockfd); return 0; }
The entire program flow is roughly as follows:
After the server starts, the Acceptor is in the listening state, and then the client requests a connection. If the connection is successful, the server calls the callback newConnection to send "how are you" to the client, and the client prints it out after accepting it.
The error situation is described below:
Using gdb debugging, it is found that every time::write(sockfd, "how are you?\n", 13);
will receiveSIGPIPE
Then the program dies.
After checkingProgram received signal SIGPIPE, Broken pipe., the reason is said to be writing to invalid (not connected or disconnected) sockfd. But when my program runs to the write of the callback function, the connection does not close. (For debugging, I also commented out the close that appears in all codes)
In addition, when debugging gdb to write, I also usedll /proc/pid/fd
to check the current system occupation descriptor, and connfd still exists.
So I don’t understand why there is SIGPIPE at all, please give me some advice!
Solved, the reason is that the third parameter of ::accept is incorrectly passed
In my code, the accept wrapper is as follows:
The calling code is
The error should be that the third parameter of ::accpet should be passed the size of the original sockaddr_in instead of the size of the converted sockaddr. Modified as follows:
Post a
man 2 accept
: