TCP 连接被拒绝 C++

TCP connection refused c++

我在连接到我的 TCP 服务器套接字时遇到问题。我以前用过它,但在添加线程后我只用 g++ main.cpp 编译它时遇到问题,不得不使用更高版本,之后它就无法连接。线程真的不应该干扰 TCP 连接的执行。似乎可能是缺少编译器版本或标志可能是问题所在,但我不确定。

我禁用了防火墙,也尝试过打开防火墙并接受连接,但没有成功。

我的客户端返回错误 "Connection refused"。

Wireshark 数据包仅显示两个数据包,这是有道理的,因为握手尚未完成。

我用g++ main.cpp -std=gnu++2a -pthread编译服务器,用./a.out编译运行,用g++ testClientSocket.cpp -o testClient -std=gnu++2a -pthread编译客户端,用[=18]编译客户端运行 =]

服务器在另一个文件中调用,代码为:

int main(){
    ServerSocket ss = ServerSocket(4000, "127.0.0.1");
}

客户端在另一个文件中调用:

int main(){
    SocketClient s = SocketClient(4000, "127.0.0.1");
} 

服务器代码:

#include <sys/socket.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <unistd.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <mutex>
#include <thread>
#include "./Worker.cpp"

#include <vector>
using namespace std;

class ServerSocket{
public:
    ServerSocket(int PORT, string ip_address){
        Worker worker_threads(4);
        worker_threads.start(); // Create a worker loop

        mutex worker_lock; // Lock for avoiding race conditions.

        int serverFd = socket(AF_INET, SOCK_STREAM, 0); // File descriptor, -1 on error
        if(serverFd == -1) cerr << "Socket creation failed" << endl;
        bool runThreads = true;

        //Datastructure for storing address
        struct sockaddr_in server;

        int addressLength = sizeof(server);

        // reuse SOCKET AND ADDRESS/PORT
        int opt = 0;
        if(setsockopt(serverFd, SOL_SOCKET, SO_REUSEADDR , &opt, sizeof(opt))) perror("setsockopt failed");


        //Bind socket to port/ip
        bind(serverFd, (sockaddr*)&server, sizeof(server));


        //Initializes the address datastructure with appropriate addresses.
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = INADDR_ANY;
        server.sin_port = htons(PORT);



        //Listen for incoming connections
        int listenStatus = listen(serverFd, SOMAXCONN);  //SOMAXCONN max queue length acc. to os.
        if(listenStatus == -1) perror("listen error");

        //Serves as event loop for server at this time. Will maybe change this later
        while(runThreads) {
            sockaddr_in client;
            socklen_t clientSize = sizeof(client);

            int new_socket = accept(serverFd, (struct sockaddr *)&client,(socklen_t*)&clientSize);
            if (new_socket == -1) perror("accept failed");
            else cout << "Connection established" << endl;
            cout << "after accept" << endl;

            connections.push_back(new_socket); //Push filedescriptor to connection to vector.

            threads.emplace_back([this, new_socket, &worker_threads, &worker_lock]{
                lock_guard<mutex> lock(worker_lock); // lock for code block
                //worker_threads.post() // POST WORK TO WORKER



            });


        }
    }

    void broadcastBallot(string message){
        //May need to message from string to bytes or something else for efficiency and logistics.

        //Connections only have filedescriptors
        //Send message to connected clients
        for(auto &con : connections){
            send(con, message.c_str() , strlen(message.c_str()) , 0 );
        }
    }

    void setCastedVotes(){
        //Readbuffer
        char readBuffer[1024] = {0};
        //May need a buffer for each connection, or use the same for all connections.

        for(auto &con :  connections){
            //Read incoming stream to bufferArray
            int readStatus  = read(con , readBuffer, 1024);
            cout << readStatus << endl;

            //Print out from readBuffer
            printf("%s\n", readBuffer );

            //TODO: SHOULD SET AN ARRAY OR SOMETHING
        }

    }


private:
    vector<int> connections;
    vector<thread> threads;



}; 

客户代码:

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <netinet/in.h>
#include <iostream>
#include <string>
#include <cstring>




using namespace std;


class SocketClient{
public:
    SocketClient(int PORT, string ip_addr){

        //Create socket
        int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
        if(sock_fd == -1) cerr << "Socket creation failed" << endl;

        //For storing information about address and port etc.
        struct sockaddr_in address;

        //Initializing address etc.
        address.sin_family = AF_INET;
        address.sin_port = htons(PORT);
        inet_pton(AF_INET, ip_addr.c_str(), &address.sin_addr);


        //Connect to serversocket
        int connection = connect(sock_fd, (sockaddr*)&address, sizeof(address));
        if(connection == -1) {
            perror("Cannot connect\n");
        }

        string helloMsg = "hello";
        int sendResult = send(sock_fd, helloMsg.c_str(), helloMsg.size()+1,0);

        char readBuffer[1024];

        while(true){
            int readResult = recv(sock_fd, readBuffer, 1024,0);
            printf("%s\n", readBuffer );
        }


    }

private:


};

这里的一个错误是服务器地址在调用bind之后被初始化。所以它的内容在那个调用中是未定义的(因此取决于编译器、OS 和月相)。很有可能就是这个问题。

此外,SO_REUSEADDR在代码中设置为零(即FALSE);这可能不是本意,可能会导致快速重启时出现问题。