send() 使我的程序崩溃
我正在运行服务器和客户端。我正在我的计算机上测试我的程序。
这是服务器中向客户端发送数据的函数:
int sendToClient(int fd, string msg) {
cout << "sending to client " << fd << " " << msg <<endl;
int len = msg.size()+1;
cout << "10\n";
/* send msg size */
if (send(fd,&len,sizeof(int),0)==-1) {
cout << "error sendToClient\n";
return -1;
}
cout << "11\n";
/* send msg */
int nbytes = send(fd,msg.c_str(),len,0); //CRASHES HERE
cout << "15\n";
return nbytes;
}
当客户端退出时,它向服务器发送“BYE”,服务器用上述函数回复它。我将客户端连接到服务器(在一台计算机、2 个终端上完成),当客户端退出时,服务器崩溃 - 它永远不会打印 15
。 知道为什么吗?知道如何测试原因吗?
谢谢。
编辑:这就是我关闭客户端的方式:
void closeClient(int notifyServer = 0) {
/** notify server before closing */
if (notifyServer) {
int len = SERVER_PROTOCOL[bye].size()+1;
char* buf = new char[len];
strcpy(buf,SERVER_PROTOCOL[bye].c_str()); //c_str - NEED TO FREE????
sendToServer(buf,len);
delete[] buf;
}
close(_sockfd);
}
顺便说一句,如果我跳过此代码,意味着只需离开 close(_sockfd)
而不通知服务器一切正常 - 服务器不会崩溃。
编辑2:这是 strace.out 的结尾:
5211 recv(5, "BYE\0", 4, 0) = 4
5211 write(1, "received from client 5 \n", 24) = 24
5211 write(1, "command: BYE msg: \n", 19) = 19
5211 write(1, "BYEBYE\n", 7) = 7
5211 write(1, "response = ALALA!!!\n", 20) = 20
5211 write(1, "sending to client 5 ALALA!!!\n", 29) = 29
5211 write(1, "10\n", 3) = 3
5211 send(5, "\t\0\0\0", 4, 0) = 4
5211 write(1, "11\n", 3) = 3
5211 send(5, "ALALA!!!\0", 9, 0) = -1 EPIPE (Broken pipe)
5211 --- SIGPIPE (Broken pipe) @ 0 (0) ---
5211 +++ killed by SIGPIPE +++
损坏的管道可以杀死我的程序?为什么不直接通过 send() 返回 -1 呢?
I'm running a server and a client. i'm testing my program on my computer.
this is the funcion in the server that sends data to the client:
int sendToClient(int fd, string msg) {
cout << "sending to client " << fd << " " << msg <<endl;
int len = msg.size()+1;
cout << "10\n";
/* send msg size */
if (send(fd,&len,sizeof(int),0)==-1) {
cout << "error sendToClient\n";
return -1;
}
cout << "11\n";
/* send msg */
int nbytes = send(fd,msg.c_str(),len,0); //CRASHES HERE
cout << "15\n";
return nbytes;
}
when the client exits it sends to the server "BYE" and the server is replying it with the above function. I connect the client to the server (its done on one computer, 2 terminals) and when the client exits the server crashes - it never prints the 15
.
any idea why ? any idea how to test why?
thank you.
EDIT: this is how i close the client:
void closeClient(int notifyServer = 0) {
/** notify server before closing */
if (notifyServer) {
int len = SERVER_PROTOCOL[bye].size()+1;
char* buf = new char[len];
strcpy(buf,SERVER_PROTOCOL[bye].c_str()); //c_str - NEED TO FREE????
sendToServer(buf,len);
delete[] buf;
}
close(_sockfd);
}
btw, if i skipp this code, meaning just leave the close(_sockfd)
without notifying the server everything is ok - the server doesn't crash.
EDIT 2: this is the end of strace.out:
5211 recv(5, "BYE\0", 4, 0) = 4
5211 write(1, "received from client 5 \n", 24) = 24
5211 write(1, "command: BYE msg: \n", 19) = 19
5211 write(1, "BYEBYE\n", 7) = 7
5211 write(1, "response = ALALA!!!\n", 20) = 20
5211 write(1, "sending to client 5 ALALA!!!\n", 29) = 29
5211 write(1, "10\n", 3) = 3
5211 send(5, "\t\0\0\0", 4, 0) = 4
5211 write(1, "11\n", 3) = 3
5211 send(5, "ALALA!!!\0", 9, 0) = -1 EPIPE (Broken pipe)
5211 --- SIGPIPE (Broken pipe) @ 0 (0) ---
5211 +++ killed by SIGPIPE +++
broken pipe can kill my program?? why not just return -1 by send()??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可能需要在标志中指定 MSG_NOSIGNAL:
You may want to specify MSG_NOSIGNAL in the flags:
您之所以收到 SIGPIPE,是因为 Unix 中的一项“功能”会在尝试在远程对等方已关闭的套接字上发送数据时引发 SIGPIPE。由于您不处理信号,因此会调用默认信号处理程序,并且它会中止/崩溃您的程序。
要获得您想要的行为(即使 send() 返回错误,而不是发出信号),请将其添加到程序的启动例程中(例如 main() 的顶部):
You're getting SIGPIPE because of a "feature" in Unix that raises SIGPIPE when trying to send on a socket that the remote peer has closed. Since you don't handle the signal, the default signal-handler is called, and it aborts/crashes your program.
To get the behavior your want (i.e. make send() return with an error, instead of raising a signal), add this to your program's startup routine (e.g. top of main()):
客户端可能在服务器完成发送之前退出,从而破坏了它们之间的套接字。从而使发送崩溃。
链接
Probably the clients exits before the server has completed the sending, thus breaking the socket between them. Thus making send to crash.
link
如果客户端在服务器第二次
发送
之前退出,并且连接未正确处理,则您的服务器将持续挂起,这可能会引发崩溃。只是猜测,因为我们不知道服务器和客户端实际做什么。
If the client exits before the second
send
from the server, and the connection is not disposed of properly, your server keeps hanging and this could provoke the crash.Just a guess, since we don't know what server and client actually do.
我发现以下代码行很奇怪,因为您定义了
int len = msg.size()+1;
。如果定义 int len = msg.size(); 会发生什么?
I find the following line of code strange because you define
int len = msg.size()+1;
.What happens if you define
int len = msg.size();
?如果您使用的是 Linux,请尝试在
strace
内运行服务器。这会将大量有用的数据写入日志文件。然后查看日志文件的末尾。也许程序做了什么以及何时崩溃是显而易见的,也许不是。在后一种情况下:在此处发布最后几行。
If you are on Linux, try to run the server inside
strace
. This will write lots of useful data to a log file.Then have a look at the end of the log file. Maybe it's obvious what the program did and when it crashed, maybe not. In the latter case: Post the last lines here.