使用 C++ 服务器-客户端的 GET 和 PUT 命令

GET and PUT commands with C++ Server-Client

我正在尝试创建服务器、客户端 put 和 get 方法,但我真的不知道从哪里开始,如何让服务器 运行 成为我处理的命令。任何帮助将不胜感激。

客户端文件

void Copy(char *filename1,char *filename2);

int main(int argc, char **argv)
{
    if(argc == 3)
    {
        int Sockfd;
        sockaddr_in ServAddr;
        hostent *HostPtr;
        int Port = atoi(argv[2]);
        int BuffSize = 0;

        // get the address of the host
        HostPtr = Gethostbyname(argv[1]);

        if(HostPtr->h_addrtype !=  AF_INET)
        {
            perror("Unknown address type!");
            exit(1);
        }

        memset((char *) &ServAddr, 0, sizeof(ServAddr));
        ServAddr.sin_family = AF_INET;
        ServAddr.sin_addr.s_addr = ((in_addr*)HostPtr->h_addr_list[0])->s_addr;
        ServAddr.sin_port = htons(Port);


        // open a TCP socket
        Sockfd = Socket(AF_INET, SOCK_STREAM, 0);

        // connect to the server
        Connect(Sockfd, (sockaddr*)&ServAddr, sizeof(ServAddr));

        char userI[256];
        // write a message to the server

        int dupSockfd = dup(Sockfd);

        FILE* writeFile = fdopen(Sockfd, "w");
        FILE* readFile = fdopen(dupSockfd, "r");

        setlinebuf(writeFile);

        char writerBuff[256];

        for(;;)
        {
            cout << "ftp> ";
            if(fgets(userI, sizeof(userI), stdin))
            {
                if(userI == "exit")
                {
                    return 1;
                }
                else
                {
                    string cmd, f1, f2;

                    istringstream iss(userI, istringstream::in);

                    iss >> cmd >> f1 >> f2;

                    cout << cmd << "." << f1 << "." << f2 << endl;



                    if(cmd == "get")
                    {
                        write(Sockfd, "get", sizeof("get"));

                        Copy(f1, f2);
                    }


                }
            }

        }

        close(Sockfd);
    }
    else
    {
        cout << "Incorrect commands for running... try './client (hostname) (port)'" << endl;
        return 1;//
    }
    return 0;//
}

void Copy(char *filename1,char *filename2) {

    const int BUFSIZE=2048;
    char buffer[BUFSIZE];
    ifstream fin;
    ofstream fout;
    long filelen, bytesRemaining, bytes;

    // Open the file to be transferred, check it exists.
    fin.open( filename1);
    if (!fin.good()) 
    {
        cerr << "Problems opening \"" << filename1 << "\" (" << errno << "): " << strerror(errno) << endl;
        exit(1);
    }
    fout.open(filename2);
    if (!fout.good()) 
    {
        cerr << "Problems opening \"" << filename2 << "\" (" << errno << "): " << strerror(errno) << endl;
        exit(1);
    }
    // Determine the file's length.
    fin.seekg(0,ios::end);
    if(fin.fail()) cerr<<"seekg() fail!\n";
    filelen = fin.tellg();
    if(fin.fail()) cerr<<"tellg() fail!\n";
    fin.seekg(0, ios::beg);
    if(fin.fail()) cerr<<"seekg() fail!\n";

    // Copy the file data.
    bytesRemaining = filelen;
    while (bytesRemaining > 0) 
    {
        bytes = bytesRemaining > BUFSIZE ? BUFSIZE : bytesRemaining;
        fin.read(buffer,bytes);
        if(fin.fail()){
            cerr<<"read() error\n";
            exit(1);
        }
        fout.write(buffer,bytes);
        if(fout.fail()){
            cerr<<"write() error\n";
            exit(1);
        }
        bytesRemaining -= bytes;
    }
    fin.close();
    fout.close();
}

服务器文件

int main(int argc, char **argv)
{
    if(argc == 2)
    {
        int Sockfd, NewSockfd, ClntLen;
        sockaddr_in ClntAddr, ServAddr;

        int Port = atoi(argv[1]);
        char String[MAX_SIZE];
        int Len;

        // open a TCP socket (an Internet stream socket)
        Sockfd = Socket(AF_INET, SOCK_STREAM, 0); // socket() wrapper fn

        // bind the local address, so that the client can send to server
        memset((char*)&ServAddr, 0, sizeof(ServAddr));
        ServAddr.sin_family = AF_INET;
        ServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        ServAddr.sin_port = htons(Port);

        int opt = 1;

        setsockopt(Sockfd,SOL_SOCKET,SO_REUSEADDR, (void*)opt, sizeof(opt)); 


        Bind(Sockfd, (sockaddr*) &ServAddr, sizeof(ServAddr));

        // listen to the socket
        Listen(Sockfd, 5);

        int RecvMsgSize;

        for(;;)
        {
            // wait for a connection from a client; this is an iterative server
            ClntLen = sizeof(ClntAddr);
            NewSockfd = Accept(Sockfd, (sockaddr*)&ClntAddr, &ClntLen);

            if((RecvMsgSize = recv(ClntSocket, EchoBuffer, RCVBUFSIZE, 0)) < 0)
            {
                perror("recv() failed"); 
                exit(1);
            }

            // read a message from the client
            Len = read(NewSockfd, String, MAX_SIZE);
            String[Len] = 0;// make sure it's a proper string
            cout<< String << endl;

            close(NewSockfd);
        }
    }
    else
    {
        cout << "Incorrect commands for running... try './server (port)'" << endl;
        return 1;//
    }
    return 0;//
}

老实说,我会使用 C++ REST API 库来完成这项工作。您可以找到一个名为 "Casablanca."

这是一个关于如何使用它来创建客户端的示例:https://casablanca.codeplex.com/wikipage?title=Http%20Client%20Tutorial

这里有一个关于如何创建服务器的例子:https://casablanca.codeplex.com/wikipage?title=HTTP%20Listener&referringTitle=Documentation

也许这会让您入门。

您想创建一个 Web 服务器来处理 GET 和 PUT 请求吗?您首先需要阅读 http 的工作原理。让我简单的解释一下。

首先尝试开发您的服务器并将其连接到浏览器:

1.Make 您的服务器侦听端口 80 - 这是必须的

2.Create 一个缓冲区,它将读取来自浏览器(客户端)的请求,就像您在这部分代码中所做的那样:

if((RecvMsgSize = recv(ClntSocket, EchoBuffer, RCVBUFSIZE, 0)) < 0)
        {
            perror("recv() failed"); 
            exit(1);
        }

        // read a message from the client
        Len = read(NewSockfd, String, MAX_SIZE);
        String[Len] = 0;// make sure it's a proper string
        cout<< String << endl;

        close(NewSockfd);

所以这个 String 对象就是你的缓冲区,它将包含 http 请求。

3.You 需要解析请求。解析请求,看方法是GET PUTPOST还是等等

这是一个示例 GET 请求:

https://marketing.adobe.com/developer/documentation/data-insertion/r-sample-http-get

4.Then 您需要将正确的响应发送回客户端,在这种情况下是浏览器:

http://pastebin.com/BPnVHym5

5.Connect 通过在地址栏中输入您的 ip 地址将您的浏览器连接到服务器