0

I have created a Socket class, everything was working perfect earlier. And just now every time I try to bind the socket server-side, it throws a bind error with message "Address already in use" while the port is free.

I am using macOS.

Should i use AF_INET or AF_UNIX?

This some of the code for the socket & bind.

// socket object class.
class Socket {
    public:
    int sock;
    string address;
    string port;
    struct addrinfo address_info;
    bool connected;

    // initialize.
    public:   
    Socket(string address__ = "", string port__ = "", bool initialize = false, int domain = -999, int type = -999, int protocol = -999) {
        address = address__;
        port = port__;
        connected = false;
        if (domain == -999) {
            //domain = AF_INET;
            domain = AF_UNIX;
            //domain = 2;
        } if (type == -999) {
            type = SOCK_STREAM;
        } if (protocol == -999) {
            protocol = 0;
        }
        memset(&address_info, 0, sizeof address_info);
        address_info.ai_family = domain;
        address_info.ai_socktype = type;
        address_info.ai_protocol = protocol;
        if (initialize) {
            print("Initialize socket...");
            sock = socket(address_info.ai_family, address_info.ai_socktype, address_info.ai_protocol);
            if (sock < 0) {
                int e = errno;
                string error = "BindError: Unable to initialize the socket.";
                print(error);
                throw BindError(error);
            }
        }
    }

    // bind server.
    public:
    int bind() {
        int optVal = 1;
        set_opt(SOL_SOCKET, SO_REUSEADDR, &optVal);
        if (address_info.ai_family == AF_UNIX) {
            //print("UNIX");
            struct sockaddr_un addr;
            memset(&addr, 0, sizeof(addr));
            addr.sun_family = AF_UNIX;
            strncpy(addr.sun_path, address.c_str(), sizeof(addr.sun_path)-1);
            int status = ::bind(sock, (struct sockaddr*)&addr, sizeof(addr));
            if (status < 0) {
                int e = errno;
                string error = "BindError: Unable to bind with "+address+":"+port+" - "+strerror(e)+".";
                print(error);
                throw BindError(error);
            }
            return status;
        }
        //print("NON UNIX");
        
        int status;
        struct addrinfo *res;
        address_info.ai_flags = AI_PASSIVE;
        if ((status = getaddrinfo(address.c_str(), port.c_str(), &address_info, &res)) != 0) {
            throw std::runtime_error("GetInfoError"); // gai_strerror(errno)
        }
        address_info.ai_addrlen = res->ai_addrlen;
        address_info.ai_addr = res->ai_addr;
        freeaddrinfo(res);

        int max_attempts = 1;
        for (int attempt = 0; attempt < max_attempts; ++ attempt) {
            status = ::bind(sock, address_info.ai_addr, address_info.ai_addrlen);
            if (status >= 0) {
                break;
            }
            if (status < 0 && attempt >= max_attempts - 1) {
                //cout << sock << " - " << address_info.ai_addr << " - " << address_info.ai_addrlen << " - " << "\n";
                int e = errno;
                string error = "BindError: Unable to bind with "+address+":"+port+" - "+strerror(e)+".";
                print(error);
                throw BindError(error);
            }
        }
        return status;
    }
};

Does anyone have an idea how to fix this?

majomere
  • 75
  • 7
  • possible dupe: https://stackoverflow.com/q/5106674 – JHBonarius May 19 '22 at 10:37
  • Not related to the error, but just out of curiousity, why are you using `-999` for the parameter defaults, instead of using actual values? `Socket(...., int domain = AF_UNIX, int type = SOCK_STREAM, int protocol = 0)` – Remy Lebeau May 19 '22 at 16:01

0 Answers0