简体   繁体   English

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

[英]Bad Request, Your browser sent a request that this server could not understand - Qt Websocket Server

I have two questions about this issue. 关于这个问题,我有两个问题。 First of all I'm trying to get the following code working 首先,我正在尝试使以下代码正常工作

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!";
    }

But this is the error that I get: 但这是我得到的错误:

"<!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"`

Has anyone got any ideas about this? 有人对此有任何想法吗?

Second question is: I'm trying to get a c++/Qt server working similar to a node js server. 第二个问题是:我正在尝试使c ++ / Qt服务器的工作类似于节点js服务器。 So I'm wanting to be able to access the connection requests in the browser. 因此,我希望能够在浏览器中访问连接请求。 So when someone connects to site:3000 I will be able to catch the request and display some content. 因此,当有人连接到site:3000时,我将能够捕获该请求并显示一些内容。 Can it be achieved with a QTcpSocket server? QTcpSocket服务器可以实现吗? If so then how could I implement something like : 如果是这样,那我该如何实现类似的东西:

// 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') {

    }
}

If this is achievable is there much speed gains in comparison to doing this in nodejs? 如果可以实现,那么与在nodejs中进行此操作相比,是否有很多速度提升? I'm personally trying to avoid js as much as possible. 我个人试图尽可能避免使用js。

if i comment the code then I can get a running program but when I try to connect on port 8000 from the browser nothing happens (just a 404 error) 如果我注释代码,那么我可以得到一个正在运行的程序,但是当我尝试从浏览器连接到端口8000时,什么也没发生(只是一个404错误)

updated answer: 更新的答案:

header file: 头文件:

#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 file .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
}

You should subclass QTCPServer. 您应该继承QTCPServer。 Set it up to listen on the port you want. 将其设置为侦听所需的端口。 This object will then get the requests and you can parse them and respond to them. 然后,该对象将获取请求,您可以解析它们并对其进行响应。

Something like this (partial code); 这样的东西(部分代码);

  #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. Here with waitForConnected , you are connecting on port 80, and waiting 3000ms maximum for the "connected state", ie not connecting on port 3000 at all. 在这里,通过waitForConnected ,您正在端口80上进行连接,并且最大等待3000ms的“连接状态”,即完全不在端口3000上进行连接。 This is the blocking way of waiting for a connection to be established, instead of connecting to the QTcpSocket::connected signal. 这是等待连接建立的阻塞方式,而不是连接到QTcpSocket::connected信号。

  2. Like Yuriy pointed out, QNetworkAccessManager is way more convenient to handle HTTP requests as a client. 就像Yuriy指出的那样, QNetworkAccessManager是作为客户端处理HTTP请求的一种更方便的方法。 As in your example, you created a TCP client, and not a server 如您的示例所示,您创建的是TCP客户端,而不是服务器

  3. Yes you can build an web server with Qt, it's a bit painfull from scratch ( QTcpServer class ), but several projects make it a bit easier: QHttpServer , QtWebApp 是的,您可以使用Qt构建Web服务器,这从头开始有点麻烦QTcpServer class ),但是一些项目使它变得更简单: QHttpServerQtWebApp

  4. If performance is your goal, I doubt you can achieve something significantly better (or just "better") without spending a lot of time on it. 如果性能是您的目标,我怀疑您可以在不花费大量时间的情况下取得明显更好的效果(或者只是“更好”)。 Namely to be able to handle a large number of request simultaneously in a fast way, a basic implementation will not be enough. 即,为了能够快速地同时处理大量请求,基本的实现是不够的。

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

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