我正在开发一个包装Berkley C Networking API的类,到目前为止我只有一个TCP服务器/客户端。
我具有讽刺意味的问题不在于网络,而在于堆栈和堆。也许我完全不理解它,但当我使用类似的东西时:
ClientSocket *mysock = new ClientSocket();
只需使用 - >调用函数即可。运算符,它工作得很好 - 如果发生错误,我的SocketException类没有问题。
但是,当我使用时:
ClientSocket mysock;
使用the调用函数时会抛出任何异常。运营商,它显示:
terminate called after throwing an instance of 'SocketException'
Aborted
然后把我扔回终端提示。
忘记添加,我在try / catch块中包装调用。
我知道第一个例子是使用'new'关键字返回指向堆上新ClientSocket实例的指针,第二个示例是堆栈,但我不知道问题。
我在想我错过了关于指针/引用/堆栈/堆的东西,但我不知道发生了什么。代码通常运行得很好,但如果抛出任何异常....> :(
编辑:在链接页面上,Client.cxx和Server.cxx是示例文件!谢谢你指出这一点,埃里克。
对此的帮助将不胜感激。该项目的来源是:
链接到所有文件:http://furryhead.co.cc/problem.html
(我无法粘贴2个以上的链接,我有4个文件,所以这个必须要做,直到有人可以将链接合并到我的帖子中)
注意:Socket.cxx相当大,因为它包含ServerSocket,ClientSocket和SocketException定义。
编译所有上述文件的命令是:
g ++ -c Socket.cxx -o Socket.o
g ++ -c Server.cxx -o Server.o
g ++ -c Client.cxx -o Client.o
g ++ Server.o Socket.o -o server
g ++ Client.o Socket.o -o client
谢谢!
根据Jon的建议,很少更新,我查找了套接字函数的文档,现在它有更好的错误报告 - 我检查'errno'变量并基于此抛出异常。 (那,我没有把它设置为非阻塞......;)) - 只是想更新并说声谢谢! :d
答案 0 :(得分:7)
对我而言,这听起来像是因为正当理由抛出的异常,并且在堆栈展开期间某些对象(可能是ClientSocket
的?)析构函数抛出。由于运行时无法以任何有意义的方式解决这种情况(同时“抛出”两个异常),因此调用terminate
函数并关闭程序。
未回答的问题是,如果某个析构函数将在其堆栈上分配它所属的对象,则会抛出这些问题。但要回答这个问题需要更多数据。也许你可以深入挖掘并测试我的假设?
顺便说一下,如果情况确实如此,并且由于没有析构函数应该ever throw anything ,我们可以得出结论,违规类是有致命缺陷。
更新:好像我有钱了。
您的班级Socket
的析构函数调用close
,close
可以抛出。这是一个严重的编程错误。您应该在
close
调用
try {
close();
}
catch(...)
{ /* this space intentionally left blank */ }
并且崩溃将消失。
第二次更新(不再崩溃)
如果recv
返回-1,则表示套接字处于非阻塞模式,并且当前没有可接收的数据。这不是错误,而是一个功能。你不应该在那里抛出异常。你应该完全做什么取决于你是想在阻塞模式还是非阻塞模式下使用套接字。
答案 1 :(得分:0)
Jon已经解决了终止问题,但原始代码中还有另一个问题。
动态分配的对象似乎有效的原因是当其他地方存在异常时,它会被泄露并且永远不会调用析构函数。虽然这避免了双重异常问题,但它会导致另一个集合......