linux - 客户-服务器程序错误Program received signal SIGPIPE, Broken pipe.

【字号: 日期:2022-08-08浏览:47作者:雯心

问题描述

先上代码:

//servervoid 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();}//clientint 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] = {’0’}; read(sockfd, buf, sizeof(buf)); //接受msg printf('Received: %sn', buf); close(sockfd); return 0;}

整个程序流程大致如下:server启动之后Acceptor处于listen状态,然后client请求连接,连接成功server就调用回调newConnection发送“how are you”给client,client接受之后打印出来。

下面说下错误情况:使用gdb调试发现每次在::write(sockfd, 'how are you?n', 13);就会接收到SIGPIPE然后程序死掉。

查了下Program received signal SIGPIPE, Broken pipe.的原因,都说是对无效(未连接或者连接断开)的sockfd进行write。但是我的程序运行到回调函数的write时也没有出现关闭连接的情况。(为了调试我还把所有代码中出现的close都注释掉)

另外,gdb调试到write的时候,我还用ll /proc/pid/fd查看了当前系统占用描述符,connfd也还存在着。

所以完全搞不懂为什么还会有SIGPIPE,求指教!

问题解答

回答1:

已解决,原因是::accept的第三个参数传错

我的代码中,accept wrapper如下:

Accept(int listenfd, struct sockaddr *addr){ socklen_t len = sizeof(*addr); int connfd = ::accept(listenfd, addr, &len); //...}

调用代码为

struct sockaddr_in addr;//...int connfd = Accept(listenfd, &addr);

错误应该是在于::accpet的第三个参数,传递的应该是原sockaddr_in的大小而不是转换后的sockaddr的大小。修改如下:

Accept(int listenfd, struct sockaddr_in *addr){ socklen_t len = sizeof(*addr); int connfd = ::accept(listenfd, (struct sockadr*)addr, &len); //...}

贴一个man 2 accept:

The addrlen argument is a value-result argument: the caller must initialize it to contain the size (in bytes) of the structure pointed to by addr; on return it will contain the actual size of the peer address.

相关文章: