我用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)};
}
谢谢你的帮助
1条答案
按热度按时间yqkkidmi1#
请输入以下网址:http:/: www.ssl3_record.c://ssl3_record.cn
这意味着您的服务器收到的是一个普通的HTTP请求(或ws://),而不是HTTPS请求(或wss://)。因此,这个特定的问题不是在您的服务器中,而是前端以错误的方式访问服务器。