我想实现一个'flexible' TCP连接,我可以随机关闭并重启服务器和客户端 . 然后另一个应该自动检测关机并输入尝试重新连接 . 我成功实施了这个s.t.我可以关闭并重启服务器 . 客户端发现关闭(通过 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初学者,所以如果有人能指出我正确的方向,我会很高兴 . 谢谢 .