简体   繁体   English

具有std :: thread强制转换变量的c ++多线程服务器

[英]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 * ,也不需要使用mallocnew为那些参数创建存储空间,您只需将线程需要的参数直接传递给线程构造函数即可。

Your program, in fact, has a memory leak. 实际上,您的程序存在内存泄漏。 It never reclaims the space it malloc s for csock to point to. 它从不回收malloc csockcsock指向的空间。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM