Geben Sie zunächst den Code ein:
//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;
}
Der gesamte Programmablauf ist ungefähr wie folgt:
Nachdem der Server gestartet ist, befindet sich der Akzeptor im Überwachungsstatus und der Client fordert eine Verbindung an. Wenn die Verbindung erfolgreich ist, ruft der Server den Rückruf newConnection auf, um „Wie geht es Ihnen?“ zu senden " an den Kunden, und der Kunde druckt es aus, nachdem er es akzeptiert hat.
Die folgende Fehlersituation ist:
Beim GDB-Debugging habe ich festgestellt, dass jedes Mal ::write(sockfd, "how are you?n", 13);
就会接收到SIGPIPE
das Programm abstürzt.
Ich habe überprüft: Programm hat Signal SIGPIPE empfangen, Pipe defekt.Der Grund soll darin liegen, dass in ein ungültiges (nicht verbundenes oder getrenntes) Sockfd geschrieben wird. Aber wenn mein Programm zum Schreiben der Rückruffunktion ausgeführt wird, wird die Verbindung nicht geschlossen. (Zum Debuggen habe ich auch den Abschluss auskommentiert, der in allen Codes erscheint)
Außerdem habe ich beim Debuggen von GDB zum Schreiben auch ll /proc/pid/fd
verwendet, um den aktuellen Systembelegungsdeskriptor zu überprüfen, und connfd ist immer noch vorhanden.
Ich verstehe also nicht, warum es SIGPIPE überhaupt gibt, bitte gebt mir einen Rat!
已解决,原因是::accept的第三个参数传错
我的代码中,accept wrapper如下:
调用代码为
错误应该是在于::accpet的第三个参数,传递的应该是原sockaddr_in的大小而不是转换后的sockaddr的大小。修改如下:
贴一个
man 2 accept
: