我来自Java所以这对我来说很难理解..我正在编写一个客户端/服务器程序来开始学习C ++。
ServerSocket server(30000);
while (true) {
ServerSocket new_sock;
server.accept(new_sock);
std::cout << "client connected...\n";
ClientConnectionThread *cct = new ClientConnectionThread(new_sock);
cct->start();
}
当我尝试写入ClientConnectionThread中的套接字时出现问题。
client_sock << someObj;
Exception was caught in cct: Could not write to socket.
我的假设是在cc-&gt; start()之后;命令ServerSocket将丢失“范围”并从堆栈中弹出并自动关闭。为了解决这个问题,我将代码更改为:
ServerSocket server(30000);
while (true) {
ServerSocket *new_sock; <----
server.accept(new_sock);
std::cout << "client connected...\n";
ClientConnectionThread *cct = new ClientConnectionThread(new_sock);
cct->start();
}
但程序甚至没有进入循环..没有错误消息告诉我为什么不起作用(当然改变必要的代码来接受指针)。
如果不明白我想要做什么..我希望在每个客户端连接上创建一个新线程来处理每个客户端。当然线程需要对套接字的引用来接收和发送 - 这就是我将它传递给CCT对象的原因。
如果您需要更多代码,请与我们联系。
答案 0 :(得分:1)
你的第一段代码并不完全正常,因为你所说的。该对象在堆栈上分配,但一旦它离开作用域,它就会被销毁,因此关闭套接字的底层指针。
如果要保持对象“活动”,则需要使用指针。你做对了,但错过了一个重点:你要分配对象!为此,您需要使用运算符new
,如下所示:
ServerSocket *new_sock = new ServerSocket;
现在,抓住这个问题,在Java上你的对象会被GC自动解除分配,但是C ++没有垃圾收集器,所以你需要手动完成。完成对象后,需要delete
。
delete new_sock;
这可能很棘手,可能导致很多崩溃甚至内存泄漏。如果你希望某些行为更像Java的GC,你可以使用shared_ptr
,它会自动解除分配对象(不是那么简单,但你可以在Google上轻松找到更多相关内容。)
std::shared_ptr<ServerSocket> new_sock = std::shared_ptr<ServerSocket>(new ServerSocket);
server.accept(*new_sock);
(假设您正在编译C ++ 11)
答案 1 :(得分:1)
如果您将一个副本而不是ServerSocket的引用传递给您的线程,您可以使您的第一个版本工作(如果可能的话 - 服务器套接字需要一个适当的复制构造函数)。您指出的原始ServerSocket将超出范围,现在不再是问题,因为副本仍然有效。
如果这不适合您,请使用Rogiel指出的版本(并坚持使用独特和共享指针等资源句柄,如果您习惯GC,这些会让您的生活更轻松:-))。