3

Everything compiles without errors and warnings. I start the program. I visit localhost:8080 and the program stops - great. I try to run the program again and I get Error: unable to bind message. Why?

Code:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <errno.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define PORT 8080
#define PROTOCOL 0
#define BACKLOG 10

int main()
{
  int fd;
  int connfd;

  struct sockaddr_in addr; // For bind()
  struct sockaddr_in cliaddr; // For accept()
  socklen_t cliaddrlen = sizeof(cliaddr);

  // Open a socket
  fd = socket(AF_INET, SOCK_STREAM, PROTOCOL);
  if (fd == -1) {
    printf("Error: unable to open a socket\n");
    exit(1);
  }

  // Create an address
  //memset(&addr, 0, sizeof addr);
  addr.sin_addr.s_addr = INADDR_ANY;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(PORT);

  if ((bind(fd, (struct sockaddr *)&addr, sizeof(addr))) == -1) {
    printf("Error: unable to bind\n");
    printf("Error code: %d\n", errno);
    exit(1);
  }

  // List for connections
  if ((listen(fd, BACKLOG)) == -1) {
    printf("Error: unable to listen for connections\n");
    printf("Error code: %d\n", errno);
    exit(1);
  }

  // Accept connections
  connfd = accept(fd, (struct sockaddr *) &cliaddr, &cliaddrlen);
  if (connfd == -1) {
    printf("Error: unable to accept connections\n");
    printf("Error code: %d\n", errno);
    exit(1);
  }

  //read(connfd, buffer, bufferlen);
  //write(connfd, data, datalen);
  //  close(connfd);

  return 0;
}
chuckfinley
  • 2,577
  • 10
  • 32
  • 42

4 Answers4

5

Use the SO_REUSEADDR socket option before calling bind(), in case you have old connections in TIME_WAIT or CLOSE_WAIT state.

Uses of SO_REUSEADDR?

Community
  • 1
  • 1
Barmar
  • 741,623
  • 53
  • 500
  • 612
2

In order to find out why, you need to print the error; the most likely reason is that another program is already using the port (netstat can tell you).

Your print problem is that C format strings use %, not &. Replace the character in your print string, and it should work.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
1

First, have a look into the following example: Socket Server Example

Second: The reason why the second bind fails is, because your application crashed, the socket is still bound for a number of seconds or even minutes.

Check with the "netstat" command if the connection is still open.

Flovdis
  • 2,945
  • 26
  • 49
1

Try putting the following code just before bind()

int opt = 1; if (setsockopt(<Master socket FD>, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt))<0) {perror("setsockopt");exit(EXIT_FAILURE);}if(setsockopt(<Master socket FD>, SOL_SOCKET, SO_REUSEPORT, (char *)&opt, sizeof(opt))<0) { perror("setsockopt");exit(EXIT_FAILURE);}

Reason behind socket bind error 98:

Socket is 4 tuple (server ip, server port , client ip, client port) When any two sockets tuples matches , error 98 is thrown When you terminate the code on server side, it means you are ending connection with tcp client . Now server is the one which sends FIN to client and goes to TIME_WAIT state. Typically , in TIME_WAIT sate server sends ack packets continuously to client , assuming that if any ack gets lost in between . Time out it depends on implementation of code . It could be from 30 seconds to 2 minutes or more.

If you run the code again , server is in TIME_WAIT , hecne port is already in use . This is because any service running on server will use fixed port which is not the case with client .

That is why in real life, server will never send FIN to client .It is client who sends FIN in order to end connection. Even if client connects again before timeout of TIME_WAIT, he will be connected to server because , he will use now a different port thus socket tuple changes . If it is implemented in reverse way , if server sends FIN , there after any new connection would not be accept till timeout ends .

Why port is busy ? It is because in TIME_Wait , the one who sends FIN first, must transmit ack packets continuously till timeout expires.

V SAI MAHIDHAR
  • 167
  • 1
  • 7