我刚刚开始在c编码,我正在尝试构建一个多线程服务器,但我有一些错误 . 首先,这是我得到的代码:
while(true){
printf("waiting for a connection\n");
csock = (int*)malloc(sizeof(int));
if((*csock = accept( hsock, (sockaddr*)&sadr, &addr_size))!= -1)
{
printf("---------------------\nReceived connection from %s\n",inet_ntoa(sadr.sin_addr));
//std::thread th(&Network::SocketHandler, NULL);
std::thread th(Network::SocketHandler, (void*)csock);
th.detach();
}
else
{
fprintf(stderr, "Error accepting %d\n", errno);
}
}
}
void Network::SocketHandler(void* lp)
{
int *csock = (int*)lp;
char buffer[1024];
int buffer_len = 1024;
int bytecount;
memset(buffer, 0, buffer_len);
if((bytecount = recv(*csock, buffer, buffer_len, 0))== -1){
fprintf(stderr, "Error receiving data %d\n", errno);
}
printf("Received bytes %d\nReceived string \"%s\"\n", bytecount, buffer);
strcat(buffer, " SERVER ECHO");
if((bytecount = send(*csock, buffer, strlen(buffer), 0))== -1){
fprintf(stderr, "Error sending data %d\n", errno);
}
printf("Sent bytes %d\n", bytecount);
}
我在这行编译时遇到错误:
std::thread th(Network::SocketHandler, (void*)csock);
说:std :: thread :: thread(Callable &&, Args && ...)[with _Callable = void(Network ::)(int); _Args = {void *}]没有已知的转换参数1从''到'void(Network :: &&)(int)'
我怎样才能解决这个问题?或者是否有更好的方法来创建多线程服务器任何其他帖子的示例?
1 回答
当你明白你真正想要的是
int *
时,你为什么要传递void *
而不是int *
?只需将功能签名更改为:
并删除执行调用的代码中的强制转换:
现在,您仍然会收到错误,这将是出于不同的原因 .
Network::SocketHandler
是会员功能 . 它需要一个this
指针 . 通常,您可以使用object.SocketHandler(csock)
或objptr->SocketHandler(csock)
等语法调用此类函数 . 当你用::std::thread
这样调用它时,你没有给它一个被调用的对象 . 它没有this
指针 .你应该做的是再次将功能签名更改为:
然后你的代码就可以了 . 它不需要
this
指针 .换句话说,看起来你正在尝试调整最初为pthreads编写的东西 . 如果我为C 11线程库执行此操作,我会以相当不同的方式执行此操作 .
我看不到你的整个节目,所以我真的没有重新设计它的奢侈 . 但是,从我所看到的,我会做出这些调整:
这些变化相当微妙 . C 11线程库允许您调用函数并提供它们的所有参数,并以线程安全的方式处理它 . 不再需要传递
void *
,也不需要使用malloc
或new
为那些参数创建存储空间,您只需将线程需要的参数直接传递给线程构造函数即可 .事实上,你的程序有内存泄漏 . 它永远不会回收
csock
指向的空间 . 如果它运行了很长时间,它最终将耗尽内存,因为所有这些文件句柄的空间从未被回收 .您的程序可能还有文件句柄泄漏 .
Network::SocketHandler
中的套接字似乎不是close
. 但是因为我不确定这一点 .