[英]c++ multithreaded server with std::thread casting variables
im just started coding in c++ and i am trying to build a multithreaded server but i got some errors. 我刚刚开始用C ++编写代码,我正在尝试构建多线程服务器,但是出现了一些错误。 first, here is the code i got:
首先,这是我得到的代码:
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);
}
i am getting a error when compiling at this line: 在此行编译时出现错误:
std::thread th(Network::SocketHandler, (void*)csock);
saying: std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (Network:: )(int ); 说:std :: thread :: thread(_Callable &&,_Args && ...)[with _Callable = void(Network :: )(int ); _Args = {void*}] no known conversion for argument 1 from '' to 'void (Network:: &&)(int )'
_Args = {void *}]没有将参数1从''转换为'void(Network :: &&)(int )'的已知转换
how can i fix this? 我怎样才能解决这个问题? or is there a better way to create a multithreaded server any examples maybe of other posts?
还是有更好的方法来创建多线程服务器?
Why are you passing in a void *
instead of an int *
when it's clear that what you really want is an int *
? 当您清楚您真正想要的是
int *
时,为什么要传递void *
而不是int *
?
Just change the function signature to: 只需将函数签名更改为:
void Network::SocketHandler(int* csock)
and remove the cast in the code that does the calling: 并在执行调用的代码中删除强制类型转换:
std::thread th(Network::SocketHandler, csock);
Now, you will still get an error, and it will be for a different reason. 现在,您仍然会收到错误,并且原因有所不同。
Network::SocketHandler
is a member function. Network::SocketHandler
是成员函数。 It needs a this
pointer. 它需要一个
this
指针。 Normally you would call such functions with syntax like object.SocketHandler(csock)
or objptr->SocketHandler(csock)
. 通常,您可以使用诸如
object.SocketHandler(csock)
或objptr->SocketHandler(csock)
类的语法来调用此类函数。 When you call it that way with ::std::thread
you aren't giving it an object to be called on. 当用
::std::thread
那样调用它时,并没有给它要调用的对象。 It has no this
pointer. 它没有
this
指针。
What you should do is change the function signature again to: 您应该做的是再次将函数签名更改为:
static void Network::SocketHandler(int* csock)
and then your code will work just fine. 然后您的代码就可以正常工作。 It doesn't look like the function makes use of any member variables, so it doesn't need a
this
pointer. 看起来该函数没有使用任何成员变量,因此不需要
this
指针。
On a different note, it looks like you're trying to adapt something originally written for pthreads. 另一方面,您似乎正在尝试改编最初为pthreads编写的内容。 If I were doing this for the C++11 thread library I would do it in a rather different manner.
如果我在C ++ 11线程库中执行此操作,则将以一种完全不同的方式执行。
I can't see your entire program, so I don't really have the luxury of re-designing it. 我看不到您的整个程序,所以我真的没有重新设计它的奢侈。 But, from what I can see, I would make these tweaks:
但是,据我所知,我将进行以下调整:
while(true){
printf("waiting for a connection\n");
int csock = -1;
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, csock);
th.detach();
}
else
{
fprintf(stderr, "Error accepting %d\n", errno);
}
}
}
void Network::SocketHandler(int csock)
{
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);
}
The changes are fairly subtle. 所做的更改相当微妙。 The C++11 thread library lets you call functions and provide all their arguments, and it handles this in a thread-safe way.
C ++ 11线程库使您可以调用函数并提供其所有参数,并且它以线程安全的方式进行处理。 There is no need to pass
void *
anymore, nor is there a need to use malloc
or new
to create storage space for those arguments you can just pass the arguments your thread needs directly to the thread constructor. 不再需要传递
void *
,也不需要使用malloc
或new
为那些参数创建存储空间,您只需将线程需要的参数直接传递给线程构造函数即可。
Your program, in fact, has a memory leak. 实际上,您的程序存在内存泄漏。 It never reclaims the space it
malloc
s for csock
to point to. 它从不回收
malloc
csock
给csock
指向的空间。 If it ran for a long time, it would eventually run out of memory as the space for all those filehandles was never reclaimed. 如果运行了很长时间,它将最终耗尽内存,因为所有这些文件句柄的空间都不会被回收。
Your program may also have a filehandle leak. 您的程序也可能存在文件句柄泄漏。 You do not appear to
close
the socket in Network::SocketHandler
. 您似乎没有
close
Network::SocketHandler
的套接字。 But since I don't have visibility on your entire program, I can't be sure about that. 但是由于我对您的整个程序不了解,因此我不确定。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.