c++ 如果有人尝试连接到我的WebSocket服务器,则出现SSL错误

rt4zxlrg  于 2022-11-27  发布在  其他
关注(0)|答案(1)|浏览(157)

我用C++编写了一个WebSocket服务器,使用了openssl@3库和Socket库中的构建。
每次我尝试从前端连接时,都会收到此错误:

00B6571701000000:error:0A00009C:SSL routines:ssl3_get_record:http request:ssl/record/ssl3_record.c:345:

我真的不知道这意味着什么,我对OpenSSL很陌生,所以我不知道如何解决这个问题。
这是我的代码:(我把它放在一个类中,因为我正在写一个项目,我不想把整个代码放在我的main.cpp中)
进口:

#include <openssl/ssl.h>
#include <openssl/err.h>
#include "netdb.h"
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <string>
#include <vector>

连接结构:

typedef struct {
    int socket;
    SSL* ssl;
    SSL_CTX* ctx;
} Connection;

下面是类的Header:

class WebSocketTCPServer{
public:
    WebSocketTCPServer();
    ~WebSocketTCPServer();

    void startServer(int port);
    void handleConnection(Connection* connection);
    void closeConnection(Connection* connection);
    void closeServer();

    void send(Connection* connection, const std::string& message);
    static std::string receive(Connection* connection);

private:
    int serverSocket;
    std::vector<Connection*> connections;
}

这里的定义是:

#include "../Websocket.h"
#include <thread>
#include <iostream>
WebSocketTCPServer::WebSocketTCPServer() {
    serverSocket = 0;
}

WebSocketTCPServer::~WebSocketTCPServer() {
    closeServer();
}

void WebSocketTCPServer::startServer(int port) {
    //command to create a self signed certificate: openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 3650
    SSL_library_init();
    OpenSSL_add_all_algorithms();
    SSL_load_error_strings();

    const SSL_METHOD* method = TLSv1_2_server_method();
    SSL_CTX* ctx = SSL_CTX_new(method);
    if (ctx == NULL) {
        ERR_print_errors_fp(stderr);
        abort();
    }

    if (SSL_CTX_use_certificate_file(ctx, "cert.pem", SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        abort();
    }

    if (SSL_CTX_use_PrivateKey_file(ctx, "key.pem", SSL_FILETYPE_PEM) <= 0 ) {
        ERR_print_errors_fp(stderr);
        abort();
    }

    serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket < 0) {
        perror("ERROR opening socket");
        exit(1);
    }

    int optval = 1;
    setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int));
    struct sockaddr_in serveraddr{};
    bzero((char *) &serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serveraddr.sin_port = htons((unsigned short)port);
    if (bind(serverSocket, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0) {
        perror("ERROR on binding");
        exit(1);
    }

    if (listen(serverSocket, 5) < 0) {
        perror("ERROR on listen");
        exit(1);
    }

    std::cout << "ws://localhost:" << port << std::endl;

    while (true) {
        struct sockaddr_in clientaddr{};
        socklen_t clientlen = sizeof(clientaddr);
        int clientSocket = accept(serverSocket, (struct sockaddr *) &clientaddr, &clientlen);
        if (clientSocket < 0) {
            perror("ERROR on accept");
            exit(1);
        }

        auto* connection = new Connection();
        connection->socket = clientSocket;
        connection->ctx = ctx;
        connection->ssl = SSL_new(ctx);
        SSL_set_fd(connection->ssl, clientSocket);

        if (SSL_accept(connection->ssl) <= 0) {
            ERR_print_errors_fp(stderr);
        } else {
            connections.push_back(connection);
            std::thread t(&WebSocketTCPServer::handleConnection, this, connection);
            t.detach();
        }
    }

    SSL_CTX_free(ctx);
}

void WebSocketTCPServer::handleConnection(Connection *connection) {
    //read msg and print it
    std::string msg = receive(connection);
    printf("%s", msg.c_str());
}

void WebSocketTCPServer::closeConnection(Connection *connection) {
    close(connection->socket);
    connections.erase(std::remove(connections.begin(), connections.end(), connection), connections.end());
    delete connection;
}

void WebSocketTCPServer::closeServer() {
    for(Connection* connection : connections) {
        closeConnection(connection);
    }
    close(serverSocket);
}

void WebSocketTCPServer::send(Connection *connection, const std::string& message) {
    ::send(connection->socket, message.c_str(), message.length(), 0);
}

std::string WebSocketTCPServer::receive(Connection *connection) {
    char buffer[1024] = {0};
    int valread = recv(connection->socket, buffer, 1024, 0);
    return {buffer, static_cast<size_t>(valread)};
}

谢谢你的帮助

yqkkidmi

yqkkidmi1#

请输入以下网址:http:/: www.ssl3_record.c://ssl3_record.cn
这意味着您的服务器收到的是一个普通的HTTP请求(或ws://),而不是HTTPS请求(或wss://)。因此,这个特定的问题不是在您的服务器中,而是前端以错误的方式访问服务器。

相关问题