c++ Server-Client中的GET和PUT命令

GET and PUT commands with C++ Server-Client

本文关键字:PUT 命令 GET Server-Client 中的 c++      更新时间:2023-10-16

我试图创建一个服务器,客户端放置和获取方法,但我真的不知道从哪里开始,我如何使服务器运行我处理的命令。如有任何帮助,不胜感激。

客户机文件

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() errorn";
            exit(1);
        }
        fout.write(buffer,bytes);
        if(fout.fail()){
            cerr<<"write() errorn";
            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;//
}

您想创建一个处理GET和PUT请求的Web服务器吗?首先需要了解http是如何工作的。让我简单地解释一下。

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

1。让您的服务器监听端口80 -这是必须的

2。创建一个将从浏览器(客户端)读取请求的缓冲区,正如您在这部分代码中所做的那样:

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);

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

3。您需要解析请求。解析请求,查看方法是否为GET PUT POST或其他。

这是一个示例GET请求:

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

4。然后,您需要将正确的响应发送回客户端(在本例中是浏览器):

http://pastebin.com/BPnVHym5

5。在地址栏

中输入您的ip地址,将浏览器连接到服务器。

我会诚实地使用c++ REST API库来完成这项工作。你可以找到一部叫《卡萨布兰卡》的。

下面是一个如何使用它来制作客户端的示例:https://casablanca.codeplex.com/wikipage?title=Http%20Client%20Tutorial

下面是一个关于如何创建服务器的示例:https://casablanca.codeplex.com/wikipage?title=HTTP%20Listener&referringTitle=Documentation