我在 C++ 中对 netcat 的尝试不会让我从服务器得到回复

My attempt at netcat in C++ won't get me replies from the server

我已经尝试在使用套接字的 C++ 程序中使用 netcat。它似乎能够生成套接字、连接并可能发送数据,但似乎有一个我找不到的错误。它没有正确地 return 来自服务器的回复。我能够 连接 到我的 HTTP 服务器并且 scanme.nmap.org 很好,但是每当我通过发送 HEAD / HTTP/1.1 (横幅抓取)来测试它时 没有显示来自服务器的任何响应。感觉我已经制作了这个程序,如果它在生成套接字、连接、发送我的输入时出错,它会提醒我并终止我知道它在执行这些操作时没有问题。所以我知道 该程序正在正常运行,但它发送数据的方式或处理回复的方式肯定存在问题。有趣的是,当连接到我的路由器时,我能够得到一个正确的响应,这与我从 netcat

得到的相同 400 Bad Request

编辑:我忘记了我的代码。立即添加

编辑:那里

#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <cstring>
#include <stdlib.h>

using namespace std;

int main (int argc, char** argv) {
        if (argv[1] == NULL) {
                cout << "3[31mTARGET NOT SPECIFIED - TERMINATING...3[0m\n";
                return -1;
        }
        if (argv[2] == NULL) {
                cout << "3[31mPORT NOT SPECIFIED - TERMINATING...3[0m\n";
                return -2;
        }

        string target = argv[1];
        int port = atoi(argv[2]);

        cout << "GENERATING SOCKET...\n";
        int chatter = socket(AF_INET, SOCK_STREAM, 0);
        if (chatter == -1) {
                cout << "3[31mSOCKET GENERATION FAILURE - TERMINATING...3[0m\n";
                return -3;
        }
        cout << "3[32mSUCCESSFULLY GENERATED SOCKET3[0m\n";

        struct sockaddr_in hint;
        hint.sin_family = AF_INET;
        hint.sin_port   = htons(port);
        inet_pton(AF_INET, target.c_str(), &hint.sin_addr);

        cout << "CONNECTING TO " << target << " AT PORT " << port << "...\n";
        int connection_status = connect(chatter, (sockaddr*)&hint, sizeof(hint));
        if (connection_status == -1) {
                cout << "3[31mCONNECTION FAILURE - TERMINATING...3[0m\n";
                return -4;
        }
        cout << "3[32mCONNECTED TO HOST3[0m\n";

        char buf[1024];
        string msg;
        while (true) {
                getline(cin, msg);
                int sendmsg = send(chatter, msg.c_str(), msg.size()+1, 0);
                if (sendmsg == -1) {                        
                        cout << "3[31mCONSISTENT MESSAGE SENDING FAILURE - TERMINATING...3[0m\n";
                        return -5;
                }
                memset(buf, 0, 1024);
                int byterecv = recv(chatter, buf, 1024, 0);
                cout << string(buf, byterecv) << "\r\n";
        }

        close(chatter);

        return 0;
}

真正的 netcat 可以从 socket 和 stdin 并行读取。您的程序可以从标准输入或套接字读取,并且这两个调用 getline()recv() 都在等待没有数据。

所以你的程序大概是:

  1. getline() 从标准输入读取一行。该行包含类似“GET ... \n”
  2. 的内容
  3. 将行发送到服务器,但它不是完整的 http 请求,因为它没有以空行结尾,所以 http 服务器没有响应并等待 http headers。
  4. 您的程序调用 recv() 并永远阻塞。

您需要更改程序的逻辑。您可以使用单独的线程从标准输入读取数据和接收数据,也可以使用 select()poll() 来等待多个文件描述符上的事件。

编辑:由于评论中的问题而进行的补充说明

HTTP 请求包括

  • 请求行
  • 请求headers(0headers有效)
  • 请求body(可以为空)

Requestheaders 和 requestbody 被一个空行跳转。即使 body 为空,也需要空行,因为服务器需要知道不再有 headers.

此外,HTTP 标准要求在行首处使用 <CR><LF>。最小有效 HTTP 请求(无 headers,空 body)是一个请求行后跟一个空行:"GET / HTTP/1.1\r\n\r\n"