c ++:如果我在两次连续的应用程序启动之间没有等待足够的时间,则 TCP 服务器 "bind" 函数失败(errno 98)

c++ : TCP Server "bind" function failed (errno 98) if I do not wait enough time between two consecutive app launch

发现TCP socket,我根据自己对题目的理解和网上找的教程做了个很简单的测试

服务器:

void Server(void)
{
  int localSocket;
  int distantSocket;

  sockaddr_in serverInfo;
  sockaddr_in clientInfo;

  int sizeOfSocketInfo = sizeof(struct sockaddr_in);

  /* Open Socket */
  std::cout << "open socket" << std::endl;

  localSocket = socket(AF_INET, SOCK_STREAM, 0);
  if (localSocket == -1)
  {
    std::cout << "open failed, error - " << (int)errno << std::endl;
    exit(errno);
  }

  /* Configure server */
  serverInfo.sin_addr.s_addr = INADDR_ANY;
  serverInfo.sin_family = AF_INET;
  serverInfo.sin_port = htons(61001);

  /* Bind Socket */
  std::cout << "bind socket" << std::endl;

  if (bind (localSocket, (sockaddr *) &serverInfo, sizeof(serverInfo)) == -1)
  {
    std::cout << "bind failed, error - " << (int)errno << std::endl;
    exit(errno);
  }

  /* Wait for client */
  std::cout << "Wait for client ..." << std::endl;

  listen(localSocket, 1);
  distantSocket = accept(localSocket, (sockaddr *)&clientInfo, (socklen_t*)&sizeOfSocketInfo);

  std::cout << "client connected  - " << inet_ntoa(clientInfo.sin_addr) << std::endl;

  /* Close Socket */
  close (localSocket);
  close (distantSocket);

  std::cout << "socket closed" << std::endl;
}

和客户:

void Client(void)
{
  int localSocket;
  sockaddr_in clientInfo;

  /* Open Socket */
  std::cout << "open socket" << std::endl;

  localSocket = socket(AF_INET, SOCK_STREAM, 0);
  if (localSocket == -1)
  {
    std::cout << "open failed, error - " << (int)errno << std::endl;
    exit(errno);
  }

  clientInfo.sin_family = AF_INET;
  clientInfo.sin_port = htons(61001);
  clientInfo.sin_addr.s_addr = inet_addr("127.0.0.1");

  /* Open Socket */
  std::cout << "connect to server" << std::endl;
  if (connect(localSocket, (sockaddr*)&clientInfo, sizeof(clientInfo)) < (int)0)
  {
    std::cout << "connect failed, error - " << (int)errno << std::endl;
    exit(errno);
  }

  std::cout << "connected !" << std::endl;

  close(localSocket);
}

当我在一个终端中启动服务器并在另一个终端中启动客户端时,似乎没问题:

服务器端:

> ./tcpTest -s
open socket
bind socket
Wait for client ...
client connected  - 127.0.0.1
socket closed
> 

和客户端:

> ./tcpTest -c
open socket
connect to server
connected !
>

但是,如果在第一次尝试之后,我再次启动服务器...

> ./tcpTest -s
open socket
bind socket
bind failed, error - 98
>

而且我必须等待 "certain time",我不知道确切的时间,也许一分钟,才能让服务器重新工作。

我不知道发生了什么,用 sockstat 打开套接字没有显示任何奇怪的东西(我只看到 mozilla 套接字)。

我发现这个人有同样的问题但是在 Ruby

如果这确实是同一个问题,我如何在 C++ 中应用相同的解决方案?或者你有什么想法吗?

谢谢

试试 setsockopt(SO_REUSEADDR),这应该会有帮助。

您可能需要同时使用 SO_REUSEADDR 和 SO_REUSEPORT。您可以进一步查看 Socket 的文档:Socket Docs

const int trueFlag = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &trueFlag, sizeof(int)) < 0)
error("Failure");

您可以使用类似的方式重用端口。希望这有帮助