C++手写HTTP Server显示监听但curl连接被拒绝求助
HTTP服务器连接拒绝问题排查与修复
我用C++编写了一个HTTP Server,运行后控制台显示:
*** Listening on ADDRESS: 127.0.0.1 PORT: 80 ***
Waiting for a new connection
但在另一个终端执行curl http://127.0.0.1/时,返回错误:curl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused,需要解决这个连接问题。
我的server.h文件
#include <iostream> #include <stdio.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdlib.h> #include <string> class Server { public: Server(); Server(std::string ip_address,int port); ~Server(); void startListen(); private: int m_socket; int port; std::string ip_address; long message_in; unsigned int m_socket_address_len; void acceptConnection(int &new_socket); std::string buildResponse(); void sendResponse(); int m_new_socket; std::string server_message; int server_start(); void close_server(); struct sockaddr_in m_socketAddress; };
我的server.cpp文件
#include "server.h" #include <sstream> #include <unistd.h> using namespace std; const int BUFFER_SIZE = 30720; Server::Server(std::string ip_address,int port) { this->ip_address = ip_address; this->port = port; this->m_socket_address_len = sizeof(m_socketAddress); this->server_message = buildResponse(); int x = server_start(); } Server::Server() { } Server::~Server() { } int Server::server_start() { m_socket = socket(AF_INET, SOCK_STREAM, 0); if(m_socket < 0) { return 1; } m_socketAddress.sin_family = AF_INET; m_socketAddress.sin_port = htons(port); m_socketAddress.sin_addr.s_addr = inet_addr(ip_address.c_str()); if (bind(m_socket,(sockaddr *)&m_socketAddress, m_socket_address_len) < 0) { return 1; } return 0; } void Server :: close_server() { close(m_socket); exit(0); } void Server :: startListen() { if(listen(m_socket,20)<0) { cout << "Connection Failed" << endl; } cout << "\n*** Listening on ADDRESS: " << inet_ntoa(m_socketAddress.sin_addr) << " PORT: " << ntohs(m_socketAddress.sin_port) << " ***\n\n"; int bytesReceived; while (true) { cout << " Waiting for a new connection " << endl; acceptConnection(m_new_socket); char buffer[BUFFER_SIZE] = {0}; bytesReceived = read(m_new_socket, buffer, BUFFER_SIZE); if (bytesReceived < 0) { cout << "Failed to read bytes from client socket connection" << endl; } cout << " Received Request from client " << endl; sendResponse(); close(m_new_socket); } } std::string Server :: buildResponse() { std::string htmlFile = "<!DOCTYPE html><html lang=\"en\"><body><h1> HOME </h1><p> Hello from your Server :) </p></body></html>"; std::ostringstream ss; ss << "HTTP/1.1 200 OK\nContent-Type: text/html\nContent-Length: " << htmlFile.size() << "\n\n" << htmlFile; return ss.str(); } void Server :: acceptConnection (int &new_socket) { new_socket = accept(m_socket, (sockaddr *)&m_socketAddress, &m_socket_address_len); } void Server :: sendResponse() { long bytesSent; bytesSent = write(m_new_socket, server_message.c_str(), server_message.size()); if (bytesSent == server_message.size()) { cout << "Server responded to client" << endl; } } int main() { //http_server = Server(); Server server = Server("127.0.0.1",80); // bind(server.m_socket, server.ip_address, sizeof()) server.startListen(); return 0; }
问题原因及修复方案
1. 特权端口权限问题
在Unix-like系统中,1-1024端口属于特权端口,普通用户无法绑定。你的程序用普通用户运行时,bind调用会失败,但代码没有处理这个错误,导致程序继续输出监听信息,实际socket并未绑定成功,无法接受连接。
修复:
- 用root权限运行程序,比如
sudo ./your_server; - 改用1024以上的端口(如8080),修改
main中的端口参数:Server server = Server("127.0.0.1",8080);,测试时用curl http://127.0.0.1:8080/。
2. 缺失错误检查逻辑
server_start中socket或bind失败时返回1,但构造函数未检查这个返回值,导致初始化失败后程序仍继续执行,输出错误的监听状态。
修复:
在构造函数中添加错误检查,初始化失败时直接退出:
Server::Server(std::string ip_address,int port) { this->ip_address = ip_address; this->port = port; this->m_socket_address_len = sizeof(m_socketAddress); this->server_message = buildResponse(); int x = server_start(); if (x != 0) { std::cerr << "服务器初始化失败:socket或bind调用出错" << std::endl; exit(EXIT_FAILURE); } }
3. accept调用未做有效性检查
accept可能调用失败,但代码未检查返回的新socket是否有效,直接执行read和write会引发错误。
修复:
在acceptConnection后添加有效性检查:
void Server :: startListen() { if(listen(m_socket,20)<0) { std::cerr << "监听失败" << std::endl; exit(EXIT_FAILURE); } cout << "\n*** Listening on ADDRESS: " << inet_ntoa(m_socketAddress.sin_addr) << " PORT: " << ntohs(m_socketAddress.sin_port) << " ***\n\n"; int bytesReceived; while (true) { cout << " Waiting for a new connection " << endl; acceptConnection(m_new_socket); if (m_new_socket < 0) { std::cerr << "接受连接失败" << std::endl; continue; } char buffer[BUFFER_SIZE] = {0}; bytesReceived = read(m_new_socket, buffer, BUFFER_SIZE); if (bytesReceived < 0) { std::cerr << "读取客户端数据失败" << std::endl; } cout << " Received Request from client " << endl; sendResponse(); close(m_new_socket); } }
内容的提问来源于stack exchange,提问作者Alphalaser
相关产品推荐
相关产品推荐

