我在C ++中尝试使用netcat不会收到服务器的回复 [英] My attempt at netcat in C++ won't get me replies from the server

查看:64
本文介绍了我在C ++中尝试使用netcat不会收到服务器的回复的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在使用套接字的C ++程序中尝试过netcat.它似乎能够生成套接字,进行连接,并且也许可以很好地发送数据,但是似乎找不到我发现的错误.它无法正确返回服务器的回复.我可以连接到我的HTTP服务器,并且scanme.nmap.org很好,但是每当我通过发送 HEAD/HTTP/1.1 (横幅广告)对其进行测试时,不显示来自服务器的任何响应.从某种意义上说,我已经制定了程序,以便如果在生成套接字,连接,发送我的输入时出错,它将提醒我并终止,我知道这样做没有问题.所以我知道该程序可以正常工作,但是它发送数据的方式或处理回复的方式都必须存在问题.有趣的是,当连接到路由器时,我能够得到与从netcat收到的 400错误请求相同的正确响应

我放弃了我的代码.立即添加

  #include< iostream>#include< sys/socket.h>#include< sys/types.h>#include< arpa/inet.h>#include< unistd.h>#include< cstring>#include< stdlib.h>使用命名空间std;int main(int argc,char ** argv){如果(argv [1] == NULL){cout<<" \ 033 [未指定31mTARGET-终止... \ 033 [0m \ n;返回-1;}如果(argv [2] == NULL){cout<<"\ 033 [未指定31mPORT-终止... \ 033 [0m \ n"";返回-2;}字符串目标= argv [1];int端口= atoi(argv [2]);cout<<生成插座... \ n";int chatter =套接字(AF_INET,SOCK_STREAM,0);如果(chatter == -1){cout<<" \ 033 [31mSOCKET生成失败-终止... \ 033 [0m \ n;返回-3;}cout<<"\ 033 [32m成功生成的套接字\ 033 [0m \ n"";struct sockaddr_in提示;hint.sin_family = AF_INET;hint.sin_port = htons(端口);inet_pton(AF_INET,target.c_str(),& hint.sin_addr);cout<<连接到"<<目标<<"在港口<<端口<<" ... \ n";int connection_status = connect(chatter,(sockaddr *)& hint,sizeof(hint));如果(connection_status == -1){cout<<"\ 033 [31m连接失败-终止... \ 033 [0m \ n"";返回-4;}cout<<"\ 033 [32m已连接到主机\ 033 [0m \ n"";char buf [1024];字符串味精;而(true){getline(cin,msg);int sendmsg = send(chatter,msg.c_str(),msg.size()+ 1,0);如果(sendmsg == -1){cout<<"\ 033 [31m一致性消息发送失败-终止... \ 033 [0m \ n";返回-5;}memset(buf,0,1024);int byterecv = recv(chatter,buf,1024,0);cout<<字符串(buf,byterecv)<<"\ r \ n";}关闭(ch);返回0;} 

解决方案

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

所以您的程序可能是:

  1. getline()从stdin读取一行.该行包含的内容类似于"GET ... \ n"
  2. 将行发送到服务器,但它不是完整的http请求,因为它不是以空行结尾,因此http服务器不响应,并等待http标头.
  3. 您的程序调用 recv()并永久阻止.

您需要更改程序的逻辑.您可以使用单独的线程从stdin中读取数据并接收数据,也可以使用 select() poll()来提供多个文件描述符上的事件等待./p>

由于评论中的问题而进行的进一步澄清

HTTP请求包含

  • 请求行
  • 请求标头(0个标头有效)
  • 请求正文(可以为空)

请求标头和请求正文由空行分隔.即使主体为空,也需要使用空行,因为服务器需要知道不再有头文件.

此外,HTTP标准在行的和处需要< CR>< LF> .最小有效的HTTP请求(无标头,空主体)是一条请求行,后跟一个空行:"GET/HTTP/1.1 \ r \ n \ r \ n"

I've made my attempt at netcat in a C++ program that uses sockets. It seems to be able to generate the socket, connect, and maybe send data fine but there seems to be an error I can't find. It doesn't properly return replies from the server. I'm able to connect to my HTTP server and scanme.nmap.org fine, but whenever I test it by sending a HEAD / HTTP/1.1 (banner grab) it doesn't show any response from the server. Sense I have made the program so that if it has an error generating a socket, connecting, sending my input, it will alert me and terminate I know that it's having no issue doing these. So I know that the program is working as it should, but there has to be either a problem with the way it sends data or with the way it handles replies. Interestingly, when connecting to my router I'm able to get a proper response which is the same 400 Bad Request I get from netcat

EDIT: I FORGOT MY CODE. ADDING THAT IN RIGHT NOW

EDIT: THERE

#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 << "\033[31mTARGET NOT SPECIFIED - TERMINATING...\033[0m\n";
                return -1;
        }
        if (argv[2] == NULL) {
                cout << "\033[31mPORT NOT SPECIFIED - TERMINATING...\033[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 << "\033[31mSOCKET GENERATION FAILURE - TERMINATING...\033[0m\n";
                return -3;
        }
        cout << "\033[32mSUCCESSFULLY GENERATED SOCKET\033[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 << "\033[31mCONNECTION FAILURE - TERMINATING...\033[0m\n";
                return -4;
        }
        cout << "\033[32mCONNECTED TO HOST\033[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 << "\033[31mCONSISTENT MESSAGE SENDING FAILURE - TERMINATING...\033[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;
}

解决方案

The real netcat can read from socket and from stdin in parallel. Your program can read either from stdin or from the socket and both of these calls getline() and recv() are waiting of there are no data.

So your program probably:

  1. getline() reads a line from stdin. The line contains something like "GET ... \n"
  2. send the line to server but it is not complete http request because it is not ended by empty line so http server does not respond and waits for http headers.
  3. Your program calls recv() and blocks forever.

You need to change the logic of your program. You can either use separate threads for reading from stdin and receiving data or you can use select() or poll() which provides waiting for an events on multiple file descriptors.

EDIT: additional clarification due to a question in comment

The HTTP request consists of

  • request line
  • request headers (0 headers are valid)
  • request body (can be empty)

Request headers and request body are diveded by an empty line. The empty line is required even if the body is empty because server needs to know that there are no more headers.

Moreover the HTTP standard requires <CR><LF> at the and of line. Minimum valid HTTP request (no headers, empty body) is a request line followed by an empty line: "GET / HTTP/1.1\r\n\r\n"

这篇关于我在C ++中尝试使用netcat不会收到服务器的回复的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆