我在 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()
都在等待没有数据。
所以你的程序大概是:
getline()
从标准输入读取一行。该行包含类似“GET ... \n” 的内容
- 将行发送到服务器,但它不是完整的 http 请求,因为它没有以空行结尾,所以 http 服务器没有响应并等待 http headers。
- 您的程序调用
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"
我已经尝试在使用套接字的 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()
都在等待没有数据。
所以你的程序大概是:
getline()
从标准输入读取一行。该行包含类似“GET ... \n” 的内容
- 将行发送到服务器,但它不是完整的 http 请求,因为它没有以空行结尾,所以 http 服务器没有响应并等待 http headers。
- 您的程序调用
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"