0

discovering TCP socket, I made a very simple test based on my understanding of the subject and some tuto found on the net

Server :

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;
}

and client :

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);
}

When I launch the server in one terminal and the client in another one, it seems to be ok :

server side :

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

and client side :

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

But, if, just after this first try, I launch the server again ...

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

And I have to wait a "certain time", I don't know exactly how long, one minute maybe, to have the server working again.

I can't figure out what's happening, looking to open socket with sockstat does not show anything strange (I only see mozilla socket).

I found this guy having the same problem but in Ruby basic Ruby TCP server demo fails on startup: `bind': Address already in use, Errno::EADDRINUSE

If this is really the same problem, how can I apply the same solution in C++ ? Or do you have any idea ?

Thank you

Community
  • 1
  • 1
Daemon Pulsar
  • 13
  • 1
  • 5
  • The "certain time" is discussed here: http://stackoverflow.com/questions/548879/releasing-bound-ports-on-process-exit – Mathieu Jan 13 '16 at 16:44

2 Answers2

4

You may need to use both SO_REUSEADDR and SO_REUSEPORT. You can further go through the documentation of Socket: Socket Docs

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

You can use reuse Port in similar way. Hope this helps

sean
  • 146
  • 2
  • 9
0

Try setsockopt(SO_REUSEADDR), this should help.

dmi
  • 1,424
  • 1
  • 9
  • 9