C++ Server 放入容器后不工作

C++ Server doesn't work after being put in a container

当 运行 正常连接我的服务器和客户端时,没有出现任何问题,所以我认为问题与 client/server 本身无关,但我会 post 无论如何。

RTCServer.cpp:

#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string.h>
#include <string>
#include <pthread.h> 

#include "Room.h"

using namespace std;

//TODO: figure out ptr situation
void* handleConnection(void* p_room) {
    Room* room = (Room *)p_room;
    int clientSocket = room->getNewest();
    char host[NI_MAXHOST];      // Client's remote name
    char service[NI_MAXSERV];   // port the client is connect on  
    memset(host, 0, NI_MAXHOST); 
    memset(service, 0, NI_MAXSERV);
       
    // accept and echo message back to client
    char buf[4096];
    while (true) {
        memset(buf, 0, 4096);
        int bytesReceived = recv(clientSocket, buf, 4096, 0);
        std::cout << "from client at " << clientSocket << "\n";
        if (bytesReceived == -1) {
            cerr << "Error in recv(). Quitting" << endl;
            break;
        }
        if (bytesReceived == 0) {
            cout << "Client disconnected " << endl;
            break;
        }
        cout << string(buf, 0, bytesReceived) << endl;

        // Echo message back to all clients
        std::vector<int> members = room->members();
        for (int i = 0; i < room->size(); i++) {
            send(members[i], buf, bytesReceived + 1, 0);
        }  
    }
    //?
    close(clientSocket);
}

int main(int argc, char *argv[]) {
    //Create a socket
    int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == -1) {
        cerr << "Can't create a socket! Quitting" << endl;
        return -1;
    }

    // Bind the ip address and port to a socket
    sockaddr_in sockInfo;
    sockInfo.sin_family = AF_INET;
    sockInfo.sin_port = htons(54000);
    inet_pton(AF_INET, "127.0.0.1", &sockInfo.sin_addr);
    bind(serverSocket, (sockaddr*)&sockInfo, sizeof(sockInfo));
    listen(serverSocket, SOMAXCONN);
    
    // Wait for a connection
    // Create new thread and handle
    Room room;
    while(1) {
        sockaddr_in client;
        socklen_t clientSize = sizeof(client);
        int clientSocket = accept(serverSocket, (sockaddr*)&client, &clientSize);
        std::cout << clientSocket << "\n";
        room.addMember(clientSocket);
        pthread_t thread;
        pthread_create(&thread, NULL, handleConnection, &room);
    }
    return 0;
}

RTCClient.cpp:

#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <string.h>
#include <string>
#include <pthread.h> 

using namespace std;

void* toServer(void* info) {
    pair<string, int>* pairPtr = (pair<string,int>*)info;
    string username = pairPtr->first;
    int sock = pairPtr->second; 
    char buf[4096];
    string userInput;
    while(1) {
        cout << "> ";
        getline(cin, userInput);
        //Send to server
        string msg = username + " :: " + userInput; 
        int sendRes = send(sock, msg.c_str(), msg.size() + 1, 0);
        if (sendRes == -1) {
            cout << "Could not send to server!\n";
            continue;
        }
    }
    return NULL;
}

void* fromServer(void* info) {    
    int sock = *(int *)info;
    char buf[4096];
    while(1) {
        memset(buf, 0, 4096);
        std::cout << "about to recv" << "\n";
        int bytesReceived = recv(sock, buf, 4096, 0);
        if (bytesReceived == -1) {
            cout << "There was an error getting a response from server\n";
        }
        //Display response
        else {
            cout << string(buf, bytesReceived) << "\n";
        }
    }  
    return NULL;
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        std::cout << "use format ./client <username>\n";
        return 1;
    }
    string username = argv[1];
    //Create a socket
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        return 1;
    }

    //Create a hint structure for the server we're connecting with
    int port = 54000;
    string ipAddress = "127.0.0.1";

    sockaddr_in hint;
    hint.sin_family = AF_INET;
    hint.sin_port = htons(port);
    inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);

    //Connect to the server on the socket
    int connectRes = connect(sock, (sockaddr*)&hint, sizeof(hint));
    std::cout << "connected" << "\n";
    if (connectRes == -1) {
        return 1;
    }
    
    pair<string, int> pairPtr = {username, sock};
    pthread_t toServerThread;
    pthread_create(&toServerThread, NULL, toServer, &pairPtr);
    

    
    pthread_t fromServerThread;
    pthread_create(&fromServerThread, NULL, fromServer, &sock);
    

    while (1) {}

    //Close the socket
    close(sock);

    return 0;
}

我用g++ *.cpp -lpthread -o <name>编译 到目前为止,我的 Dockerfile 很简单,我只想在继续之前将服务器 运行 放入容器中。

Docker 文件:

FROM ubuntu:latest
COPY server /
ENTRYPOINT ["./server"]

然后我构建图像:

docker build -t chatserver .

要运行我做的图片:

docker run -d -p 54000:80 --name chatserver chatserver

执行客户端后,没有建立实际连接,项目的功能也消失了。我怀疑我的问题与客户端和服务器端口的暴露方式有关。

您正在将 docker 容器中的端口映射到 80 - 因此要么更改您的服务器代码以绑定到端口 80,要么使用 docker ... -p 54000:54000 ...

实用提示: 在你的 devcontainer.json 添加

"appPort":["54000:54000/tcp"],

(否则使用 udp,我使用 VSCode)