docker 中的entrypoint和cmd指令

下面是一个使用C++编写的简单的服务器和客户端程序,服务器通过socket向客户端发送cmd指令,并由客户端执行。

服务器端代码:


cpp复制插入

#include <iostream>
#include <winsock2.h>
#include <string>

#pragma comment(lib, "ws2_32.lib")

int main() {
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "Failed to initialize winsock" << std::endl;
        return -1;
    }

    // 创建socket
    SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == INVALID_SOCKET) {
        std::cerr << "Failed to create socket" << std::endl;
        WSACleanup();
        return -1;
    }

    // 绑定IP和端口
    sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8888);
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    if (bind(serverSocket, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "Failed to bind socket" << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return -1;
    }

    // 监听连接
    if (listen(serverSocket, 1) == SOCKET_ERROR) {
        std::cerr << "Failed to listen on socket" << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return -1;
    }

    std::cout << "Waiting for client connection..." << std::endl;

    // 接受连接
    SOCKET clientSocket;
    sockaddr_in clientAddr{};
    int clientAddrSize = sizeof(clientAddr);
    clientSocket = accept(serverSocket, (struct sockaddr*) &clientAddr, &clientAddrSize);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "Failed to accept client connection" << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return -1;
    }

    std::cout << "Client connected" << std::endl;

    // 发送cmd指令给客户端
    std::string cmd;
    while (true) {
        std::cout << "Enter cmd command (or 'exit' to exit): ";
        std::getline(std::cin, cmd);

        // 发送cmd指令
        send(clientSocket, cmd.c_str(), cmd.size(), 0);

        if (cmd == "exit") {
            break;
        }

        // 接收客户端执行结果
        char buffer[4096];
        memset(buffer, 0, sizeof(buffer));
        if (recv(clientSocket, buffer, sizeof(buffer) - 1, 0) == SOCKET_ERROR) {
            std::cerr << "Failed to receive data from client" << std::endl;
            break;
        }

        std::cout << "Received result from client:" << std::endl;
        std::cout << buffer << std::endl;
    }

    // 关闭连接
    closesocket(clientSocket);
    closesocket(serverSocket);
    WSACleanup();

    std::cout << "Server terminated" << std::endl;

    return 0;
}

复制插入

客户端代码:


cpp复制插入

#include <iostream>
#include <winsock2.h>

#pragma comment(lib, "ws2_32.lib")

int main() {
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        std::cerr << "Failed to initialize winsock" << std::endl;
        return -1;
    }

    // 创建socket
    SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == INVALID_SOCKET) {
        std::cerr << "Failed to create socket" << std::endl;
        WSACleanup();
        return -1;
    }

    // 连接到服务器
    sockaddr_in serverAddr{};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(8888);
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    if (connect(clientSocket, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        std::cerr << "Failed to connect to server" << std::endl;
        closesocket(clientSocket);
        WSACleanup();
        return -1;
    }

    // 接收并执行服务器发来的cmd指令
    while (true) {
        char buffer[4096];
        memset(buffer, 0, sizeof(buffer));
        if (recv(clientSocket, buffer, sizeof(buffer) - 1, 0) == SOCKET_ERROR) {
            std::cerr << "Failed to receive cmd command from server" << std::endl;
            break;
        }

        std::string cmd(buffer);

        if (cmd == "exit") {
            break;
        }

        std::cout << "Received cmd command from server: " << cmd << std::endl;

        // 执行cmd指令
        FILE* pipe = _popen(cmd.c_str(), "r");
        if (!pipe) {
            std::cerr << "Failed to execute cmd command" << std::endl;
            break;
        }

        std::cout << "Executing cmd command..." << std::endl;

        std::string result;
        char buffer2[128];
        while (!feof(pipe)) {
            if (fgets(buffer2, 128, pipe) != nullptr)
                result += buffer2;
        }

        _pclose(pipe);

        // 将执行结果发送给服务器
        send(clientSocket, result.c_str(), result.size(), 0);
    }

    // 关闭连接
    closesocket(clientSocket);
    WSACleanup();

    std::cout << "Client terminated" << std::endl;

    return 0;
}

复制插入

请注意,这只是一个简单的示例程序,没有处理错误和异常情况。在实际使用中,应该进行错误处理、合理的输入验证和安全措施。

制作不易,请点赞加关注

Dockerfile 中的 `ENTRYPOINT` `CMD` 指令在功能、行为、覆盖性、语法、灵活性以及结合使用方式等方面存在区别: - **功能**:`ENTRYPOINT` 用于定义容器启动时要执行的主命令或程序;`CMD` 则是提供默认的命令或参数(如果没有提供命令时)[^3]。 - **行为**:容器启动时,`ENTRYPOINT` 设置的命令始终执行;如果没有指定其他命令,`CMD` 会作为默认命令执行[^3]。 - **覆盖**:`ENTRYPOINT` 不容易被覆盖,除非使用 `docker run` 时明确指定命令容器启动时,如果没有指定命令,`CMD` 会作为默认值,且可以被用户在 `docker run` 时提供的参数覆盖[^3]。 - **语法**:`ENTRYPOINT` 通常使用 `["executable", "param1", "param2"]` 这种 exec 格式;`CMD` 常见语法为 `["param1", "param2"]` ,也可作为完整命令 `["executable", "param1", "param2"]` 或 shell 格式 `command param1 param2` [^3]。 - **灵活性**:`ENTRYPOINT` 固定性更强,通常用于关键应用程序的启动;`CMD` 更灵活,可以被用户在 `docker run` 时覆盖[^3]。 - **结合使用**:`CMD` 可以提供默认参数给 `ENTRYPOINT`,也可以提供默认命令或者覆盖 `ENTRYPOINT`。例如,当容器启动时,默认执行 `python3 app.py --port 8080`,若在启动容器时提供了额外的参数(例如 `docker run my_image --port 9090`),那么 `--port 9090` 会替代 `CMD` 中的默认参数 `--port 8080` [^3]。 以下是使用示例: ```Dockerfile # 仅使用 ENTRYPOINT FROM ubuntu:20.04 ENTRYPOINT ["echo", "Hello"] ``` ```Dockerfile # ENTRYPOINT CMD 结合使用 FROM python:3.9 ENTRYPOINT ["python3", "app.py"] CMD ["--port", "8080"] ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值