错误请求,您的浏览器发送了此服务器无法理解的请求 - Qt Websocket Server

时间:2017-02-14 15:00:39

标签: c++ qt websocket server

我对这个问题有两个问题。 首先,我试图让以下代码正常工作

socket = new QTcpSocket(this);
    // I'm a little confused as to why we're connecting on port 80 
    // when my goal is to listen just on port 3000. Shouldn't I just 
    // need to connect straight to port 3000?
    socket->connectToHost("localhost", 80);

    if (socket->waitForConnected(3000))
    {
        qDebug() << "Connected!";

        // send
        socket->write("hello server\r\n\r\n\r\n\r\n");
        socket->waitForBytesWritten(1000);
        socket->waitForReadyRead(3000);
        qDebug() << "Reading: " << socket->bytesAvailable();

        qDebug() << socket->readAll();

        socket->close();
    }
    else
    {
        qDebug() << "Not connected!";
    }

但这是我得到的错误:

"<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n<html><head>\n<title>400 Bad Request</title>\n</head><body>\n<h1>Bad `Request</h1>\n<p>Your browser sent a request that this server could not understand.<br />\n</p>\n<hr>\n<address>Apache/2.4.18 (Ubuntu) Server at 127.0.1.1 Port 80</address>\n</body></html>\n"`

有没有人对此有任何想法?

第二个问题是:我试图使c ++ / Qt服务器与节点js服务器类似。因此,我希望能够在浏览器中访问连接请求。因此当有人连接到site:3000时,我将能够捕获请求并显示一些内容。可以使用QTcpSocket服务器实现吗?如果是这样,我怎么能实现像:

// I know this isn't valid c++, Just to give an idea of what I'm trying to achieve 
socket.on(Request $request) {
    if ($request.method() == 'GET') {

    }
}

如果这是可以实现的,那么与在nodejs中执行此操作相比,速度会有多大提升? 我个人尽量避免使用js。

如果我评论代码然后我可以得到一个正在运行的程序但是当我尝试从浏览器连接端口8000时没有任何反应(只是404错误)

更新回答:

头文件:

#ifndef SOCKETTEST_H
#define SOCKETTEST_H

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>

class SocketTest : public QTcpServer
{
public:
    SocketTest(QObject *parent);

private:
    QTcpSocket *client;

public slots:
    void startServer(int port);
    void readyToRead(void);
    void incomingConnection(int socket);
};

#endif // SOCKETTEST_H

.cpp文件

#include "sockettest.h"

SocketTest::SocketTest(QObject *parent) :
    QTcpServer(parent)
{
    this->startServer(8000);
}

void SocketTest::startServer(int port)
{
    bool success = listen(QHostAddress::Any, port); // this starts the server listening on your port
    // handle errors
}

void SocketTest::incomingConnection(int socket)
{
    // a client has made a connection to your server
    QTcpSocket *client = new QTcpSocket(this);
    //client->setSocketDescription(socket);

    // these two lines are important, they will direct traffic from the client
    // socket to your handlers in this object

    connect(client, SIGNAL(readyRead()), this, SLOT(readToRead()));
    connect(client, SIGNAL(disconnect()), this, SLOT(disconnected()));

}

void SocketTest::readyToRead(void)
{
    QTcpSocket *client = (QTcpSocket*)sender();


    qDebug() << "Just got a connection";

    // you can process requests differently here. this example
    // assumes that you have line breaks in text requests

    while (client->canReadLine())
    {
        QString aLine = QString::fromUtf8(client->readLine()).trimmed();

        // Process your request here, parse the text etc
    }
}

// this gives me the following error 
// /user_data/projects/qt/QtServer/sockettest.cpp:47: error: no ‘void 
// SocketTest::disconnected()’ member function declared in class ‘SocketTest’
 void SocketTest::disconnected()
                               ^
void SocketTest::disconnected()
{
    // jsut a qu, wont all these * vars lead to a memory leak? and shouldn't I be using a var Qtc... *client; in the header file?
    QTcpSocket *client = (QTcpSocket*)sender();

    // clean up a disconnected user
}

2 个答案:

答案 0 :(得分:0)

您应该将QTCPServer子类化。将其设置为侦听所需的端口。然后,此对象将获取请求,您可以解析它们并对它们做出响应。

像这样的东西(部分代码);

  #include <QTcpServer>
  #include <QTcpSocket>


  class mySuperNodeLikeServer : public QTcpServer
  {
      mySuperNodeLikeServer(QObject *parent);
      void startServer(int port);
      void readyToRead(void);
      void incomingConnection(int socket);
  }

 // in your .cpp file

 void mySuperNodeLikeServer::startServer(int port)
 {
     bool success = listen(QHostAddress::Any, port); // this starts the server listening on your port
     // handle errors
 }

 void mySuperNodeLikeServer::incomingConnection(int socket)
 {
     // a client has made a connection to your server
    QTcpSocket *client = new QTcpSocket(this);
    client->setSocketDescription(socket);

    // these two lines are important, they will direct traffic from the client
    // socket to your handlers in this object

    connect(client, SIGNAL(readyRead()), this, SLOT(readToRead()));
    connect(client, SIGNAL(disconnect()), this, SLOT(disconnected()));

  }

  void mySuperNodeLikeServer::readyToRead(void)
  {
     QTcpSocket *client = (QTcpSocket*)sender();

     // you can process requests differently here. this example
     // assumes that you have line breaks in text requests

     while (client->canReadLine())
     {
        QString aLine = QString::fromUtf8(client->readLine()).trimmed();

        // Process your request here, parse the text etc
     }
  }

  void mySuperNodeLikeServer::disconnected()
  {
     QTcpSocket *client = (QTcpSocket*)sender();

     // clean up a disconnected user 
  }

答案 1 :(得分:0)

  1. 此处使用waitForConnected,您正在连接端口80,并且等待连接状态&#34;最多等待3000毫秒,即根本不连接端口3000。这是等待建立连接的阻塞方式,而不是连接到QTcpSocket::connected信号。

  2. 像Yuriy指出的那样,QNetworkAccessManager作为客户端处理HTTP请求更方便。在您的示例中,您创建了一个TCP客户端,而不是服务器

  3. 是的,您可以使用Qt构建一个Web服务器,它从头开始有点痛苦(QTcpServer class),但有几个项目使它更容易:QHttpServer,{{ 3}}

  4. 如果表现是你的目标,我怀疑你可以在不花费大量时间的情况下更好地实现更好的目标(或者只是更好的&#34;)。即为了能够以快速方式同时处理大量请求,基本实现是不够的。