1

I am working in a simple socket project. I would like to know:

  1. why error messages appear before telnet localhost 5678?

  2. why SO_REUSEADDR (between socket() and bind()) don't work, and what else I should try?

Code Output Message:

bind error
Error opening file: Address already in use
telnet localhost 5678
[+]Server Socket is created.

main.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#define BUFSIZE 1024 // Buffer Size
#define PORT 5678
        
int main() {
        
    printf("telnet localhost 5678\n");
    int rfd; // socket descriptor
    int clientfd; // client descriptor
        
    struct sockaddr_in client; // Client Socket address
    socklen_t client_len; // Length of Client Data
    char input[BUFSIZE]; // Client Data -> Server
    int bytes_read; // Client Bytes
        
        
    // 1. socket() = create a socket, SOCK_STREAM = TCP
    rfd = socket(AF_INET, SOCK_STREAM, 0);
    if (rfd < 0) {
        fprintf(stderr, "socket error\n");
        exit(-1);
    }
    printf("[+]Server Socket is created.\n");
        
    // optional
    int enable = 1;
    if (setsockopt(rfd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0)
        fprintf(stderr, "setsockopt(SO_REUSEADDR) failed");
    
    //Initialize the server address by the port and IP
    struct sockaddr_in server;
    memset(&server, 0, sizeof(server));
    server.sin_family = AF_INET; // Internet address family: v4 address
    server.sin_addr.s_addr = INADDR_ANY; // Server IP address
    server.sin_port = htons(PORT); // Server port
        
    // 2. bind() = bind the socket to an address
    int brt = bind(rfd, (struct sockaddr *) &server, sizeof(server));
    if (brt < 0) {
        int errnum;
        errnum = errno;
        fprintf(stderr, "bind error\n");
        fprintf(stderr, "Error opening file: %s\n", strerror(errnum));
        exit(-1);
    }
    printf("[+]Bind to port %d\n", PORT);
        
    // 3. listen() = listen for connections
    int lrt = listen(rfd, 50);
    if (lrt < 0) {
        printf("listen error\n");
        exit(-1);
    }
    if (lrt == 0) {
        printf("[+]Listening....\n");
    }
        
    // non-stop loop
    while (1) {
        
        // 4. accept() = accept a new connection on socket from client
        clientfd = accept(rfd, (struct sockaddr *) &client, &client_len);
        if (clientfd < 0) {
            fprintf(stderr, "accept failed with error %d\n");
            exit(-1);
        }
        printf("Client connected\n");
        
        ...
        close(clientfd);
        printf("Client disconnected\n");
    }
    close(rfd);
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
user12595983
  • 137
  • 1
  • 3
  • 12
  • Is there another program actively listening on this port, or did it just recently exit? – dbush Jul 08 '21 at 15:49
  • i didn't set other programs actively listening on this port, but i don't know if another program actively listening on this port. I just work on a server side socket program. – user12595983 Jul 08 '21 at 16:01
  • 2
    Run "netstat -an" from the command line. That will tell you what ports are currently open. – dbush Jul 08 '21 at 16:02
  • the port shows listening in the past. there is no error if i run (with Clion) it at the first time, but if i compile it again, error appear. – user12595983 Jul 08 '21 at 18:18

1 Answers1

3

I'm assuming that you are using Linux. If you want to rebind to an address, you should use SO_REUSEPORT not SO_REUSEADDR. Name is really misleading. But make sure that you know how it works and whether you really want to use it or not.

You can check difference here: How do SO_REUSEADDR and SO_REUSEPORT differ?

Afshin
  • 8,839
  • 1
  • 18
  • 53