C++ Переподключение TCP-сервера к клиенту после перезапуска клиента

Я хочу реализовать "гибкое" TCP-соединение, при котором я могу произвольно завершить работу и перезапустить как Сервер, так и Клиент. Другой должен автоматически обнаружить выключение и ввести попытку повторного подключения. Я успешно реализовал эту я могу выключить и перезапустить сервер. Клиент обнаруживает выключение (через recv(...) == 0) и затем закрывает соединение (поэтому закрывает сокеты close(this->sockfd_) а также close(this->newsockfd_)).

К сожалению, я не могу заставить это работать наоборот. Я инициализирую сервер (используя конструктор класса) следующим образом:

tcpServer::tcpServer(int _port) {
  this->sockfd_ = -1;
  this->port_ = _port;
  this->connected_ = false;
  if ((this->sockfd_ = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    this->dieWithError("ERROR opening Socket");
  else
    printf("-> Port %d: Socket opened\n", this->port_);
  // get rid of "address already in use" error message
  int yes = 1;
  setsockopt(this->sockfd_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
  /* assign values to the fields of struct sockaddr_in */
  bzero((char *) &this->serv_addr_, sizeof(this->serv_addr_));
  this->serv_addr_.sin_family = AF_INET;
  this->serv_addr_.sin_port = htons(this->port_);
  this->serv_addr_.sin_addr.s_addr = INADDR_ANY;
  /* bind the socket to an address */
  if (bind(this->sockfd_, (struct sockaddr *) &this->serv_addr_, sizeof(this->serv_addr_)) < 0) {
    printf("-> Port %d:", this->port_);
    this->dieWithError("ERROR on binding");
  }
  printf("-> Binding successful. Start TCP client in new terminal\n");
  fflush(stdout);
  /* listen for connections and accept a connection */
  listen(this->sockfd_, 5);
  this->clilen_ = sizeof(this->cli_addr_);
  if ((this->newsockfd_ = accept(this->sockfd_, (struct sockaddr *) &this->cli_addr_, &this->clilen_)) < 0)
    this->dieWithError("Error on accept");
  else {
    printf("-> Connection established\n");
    this->connected_ = true;
  }
}

Поэтому, когда сервер обнаруживает, что соединение закрыто, он входит в цикл, где он пытается восстановить соединение, используя следующий код:

void tcpServer::connect() {
  if (this->sockfd_ == -1) {
    /* create socket */
    if ((this->sockfd_ = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        this->dieWithError("ERROR opening Socket");
    else
        printf("-> Port %d: Socket opened\n", this->port_);
    // get rid of "address already in use" error message
    int reuse_address = 1;
    setsockopt(this->sockfd_, SOL_SOCKET, SO_REUSEADDR, &reuse_address, sizeof(int));
    /* listen for connections and accept a connection */
    listen(this->sockfd_, 5);
    this->clilen_ = sizeof(this->cli_addr_);
    if ((this->newsockfd_ = accept(this->sockfd_, (struct sockaddr *) &this->cli_addr_, &this->clilen_)) < 0)
        this->dieWithError("Error on accept");
    else {
        printf("-> Connection established\n");
        this->connected_ = true;
    }
  }
}

Некоторые простые выходные данные отладки говорят мне, что в режиме повторного подключения сервер застревает в accept(this->sockfd_, (struct sockaddr *) &this->cli_addr_, &this->clilen_) вызов. Еще одно наблюдение, которое я сделал, заключается в том, что клиент не выключается должным образом (через ctrl-c), то есть он где-то застревает в цикле и неправильно закрывает соединение.

Поскольку я новичок в работе с TCP, я был бы очень рад, если бы кто-то указал мне верное направление. Спасибо.

0 ответов

Другие вопросы по тегам