如何告诉某个套接字从队列中获取数据?

时间:2013-01-12 13:57:24

标签: c++ multithreading qt networking

我正在编写一个C ++ / Qt多线程服务器。因为它只是更大应用程序的一部分,所以我必须将收到的所有数据写入队列。比某人的其他部分处理此信息并给出响应,也将其放入队列中。我想知道是否可以将这个响应放到某个线程中的某个套接字上,因为我到目前为止提出的唯一想法是发送响应到达的信号,唤醒所有线程和他们检查它是否是他们的消息(通过检查套接字描述符)。

我的代码:
thread.h

#pragma once
#include "socket.hpp"
#include <QThread>

class Thread : public QThread
{
    Q_OBJECT
public:
    Thread(int socketId, QObject *parent = 0);
    void run();
signals:
    void error(QTcpSocket::SocketError socketerror);
private:
    int socketDescriptor;
};

thread.cpp

#include "thread.h"
#include <iostream>

Thread::Thread(int socketId, QObject *parent) :
    QThread(parent), socketDescriptor(socketId)
{
}

void Thread::run()
{
    Socket *tcpSocket = new Socket(socketDescriptor, this);
    connect(tcpSocket, SIGNAL(connectionClosed()), SLOT(quit()));
    exec();
}

socket.h中

#pragma once

#include <QTcpSocket>
#include <boost/shared_ptr.hpp>

class Message;

class Socket : public QObject
{
    Q_OBJECT
public:
    Socket(int socketDescriptor, QObject* = 0);
    ~Socket();

    bool isActive();
    void emmiter();
signals:
    void connectionClosed();
private slots:
    void readClient();
    void discardClient();
public slots:
    void sendResponse(boost::shared_ptr<Message>);
private:
    void disconnect();
    quint16 nextBlockSize;
    QTcpSocket* socket;
};

socket.cpp

void ClientSocket::sendResponse(boost::shared_ptr<Message> msg)
{
    if(this->socket->socketDescriptor() == msg->conn.socket)
    {
            //actuall sending is not important
    }
}

这个^以上就是我知道的,但我知道它并不好,特别是如果我有很多线程并且它们都检查socketDescriptor()。此外,我必须从我的Message类创建一个元对象,以便它可以在信号槽机制中使用d。 我想把信号发送到一个插座。我该怎么做 ?将socket对象放在一个线程中,并通过向线程提供id来调用方法?有什么想法吗?

1 个答案:

答案 0 :(得分:2)

  

我想知道是否可以将此响应放在某个线程中的某个套接字上,因为我到目前为止提出的唯一想法是发送响应到达的信号,唤醒所有线程并且它们检查它是否是它们的消息(通过检查套接字描述符)。

不,那不是你怎么做的。线程就像一个员工。当你去汉堡王时,你不要求简。如果你在柜台看到杰夫,你就不要走过他,然后在后面翻找,让简接受你的订单。如果她忙于客户,但杰夫可以,你不要等Jane。您让第一个可用的收银员接受您的订单。

当您在套接字上接收数据时,拥有一个线程,任何线程,处理该信息。哪个没关系。您不需要强制某个特定的线程来执行此操作。

尽量少考虑线程。他们只是做这项工作的车辆。您应该专注于您想要完成的工作以及执行此操作的代码。如果你必须考虑过度分配工作的机制,你就会做错事。

如果您有收银员(不能做饭)和厨师(无法接受订单),您将始终四处寻找合适的员工来完成工作。但是所有的线程基本上都是平等的,并且同样能够胜任任何工作,所以如果你强迫自己进入它,你只会遇到这种噩梦。