简体   繁体   English

C ++中的多线程,从套接字接收消息

[英]Multithreading in C++, receive message from socket

I have studied Java for 8 months but decided to learn some c++ to on my spare time. 我已经学习Java 8个月了,但决定在业余时间学习一些c ++。

I'm currently making a multithreaded server in QT with minGW. 我目前正在使用minGW在QT中制作多线程服务器。 My problem is that when a client connects, I create an instance of Client( which is a class) and pass the socket in the client class contructor. 我的问题是,当客户端连接时,我会创建Client(这是一个类)的实例,并将套接字传递给客户端类构造函数。

And then I start a thread in the client object (startClient()) which is going to wait for messages, but it doesn't. 然后,我在客户端对象(startClient())中启动一个线程,该线程将等待消息,但事实并非如此。 Btw, startClient is a method that I create a thread from. 顺便说一句,startClient是我从中创建线程的方法。 See code below. 请参见下面的代码。

What happens then? 那会发生什么呢? Yes, when I try to send messages to the server, only errors, the server won't print out that a new client connects, and for some reason my computer starts working really hard. 是的,当我尝试将消息发送到服务器时,只有错误,服务器不会打印出新客户端已连接的消息,由于某种原因,我的计算机开始非常努力地工作。 And qtcreator gets super slow until I close the server-program. 在关闭服务器程序之前,qtcreator变得非常慢。

What I actually is trying to achieve is an object which derives the thread, but I have heard that it isn't a very good idea to do so in C++. 我实际上试图实现的是一个派生线程的对象,但是我听说在C ++中这样做不是一个好主意。

The listener loop in the server: 服务器中的侦听器循环:

for (;;)
    {
        if ((sock_CONNECTION = accept(sock_LISTEN, (SOCKADDR*)&ADDRESS, &AddressSize)))
        {
            cout << "\nClient connected" << endl;

            Client client(sock_CONNECTION); // new object and pass the socket
            std::thread t1(&Client::startClient, client); //create thread of the method
            t1.detach();
        }
    }

the Client class: 客户类:

Client::Client(SOCKET socket)
{
    this->socket = socket;
    cout << "hello from clientconstructor ! " << endl;
}

void Client::startClient()
{
    cout << "hello from clientmethod ! " << endl;

    // WHEN I ADD THE CODE BELOW I DON'T GET ANY OUTPUT ON THE CONSOLE!
    // No messages gets received either.
    char RecvdData[100] = "";
    int ret;
    for(;;)
    {

        try
        {
            ret = recv(socket,RecvdData,sizeof(RecvdData),0);
            cout << RecvdData << endl;
        }
        catch (int e)
        {
            cout << "Error sending message to client" << endl;
        }

    }
}

It looks like your Client object is going out of scope after you detach it. 分离对象后,看来您的Client对象超出了范围。

if (/* ... */)
{
  Client client(sock_CONNECTION);
  std::thread t1(&Client::startClient, client);
  t1.detach();
} // GOING OUT OF SCOPE HERE

You'll need to create a pointer of your client object and manage it, or define it at a higher level where it won't go out of scope. 您需要创建客户端对象的指针并进行管理,或者在不超出范围的更高级别上对其进行定义。

The fact that you never see any output from the Server likely means that your client is unable to connect to your Server in the first place. 您从未看到服务器的任何输出的事实可能意味着您的客户端一开始就无法连接到服务器。 Check that you are doing your IP addressing correctly in your connect calls. 检查您在连接呼叫中是否正确执行了IP寻址。 If that looks good, then maybe there is a firewall blocking the connection. 如果看起来不错,则可能是防火墙阻止了连接。 Turn that off or open the necessary ports. 将其关闭或打开必要的端口。

Your connecting client is likely getting an error from connect that it is interpreting as success and then trying to send lots of traffic on an invalid socket as fast as it can, which is why your machine seems to be working hard. 您的连接客户端可能会从连接中得到一个错误,该错误被解释为成功,然后尝试以最快的速度在无效套接字上发送大量流量,这就是您的计算机似乎工作正常的原因。

You definitely need to check the return values from accept, connect, read and write more carefully. 您绝对需要更仔细地检查来自接受,连接,读取和写入的返回值。 Also, make sure that you aren't running your Server's accept socket in non-blocking mode. 另外,请确保未在非阻塞模式下运行服务器的接受套接字。 I don't think that you are because you aren't seeing any output, but if you did it would infinitely loop on error spawning tons of threads that would also infinitely loop on errors and likely bring your machine to its knees. 我不认为您是因为您看不到任何输出,但是如果您这样做,它将无限循环地产生错误,从而产生大量线程,也将无限循环地产生错误,并可能使您的机器瘫痪。

If I misunderstood what is happening and you do actually get a client connection and have "Client connected" and "hello from client method ! " output, then it is highly likely that your calls to recv() are failing and you are ignoring the failure. 如果我误解了正在发生的事情,而您实际上得到了一个客户端连接,并且输出了“ Client connected”和“ client method from hello!”,那么您对recv()的调用很可能失败,而您却忽略了失败。 So, you are in a tight infinite loop that is repeatedly outputting "" as fast as possible. 因此,您处于紧密的无限循环中,该循环将尽可能快地重复输出“”。

You also probably want to change your catch block to catch (...) rather than int. 您可能还想将catch块更改为catch(...),而不是int。 I doubt either recv() or cout throw an int. 我怀疑recv()或cout抛出一个整数。 Even so, that catch block won't be invoked when recv fails because recv doesn't throw any exceptions AFAIK. 即使这样,当recv失败时也不会调用该catch块,因为recv不会抛出任何异常AFAIK。 It returns its failure indicator through its return value. 它通过其返回值返回其故障指示器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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