Cocksure
Cocksure

Reputation: 235

accept() keeps returning 0

This is a simple server that merely accepts connections, then prints the socket descriptor. For some reason, whenever I run this the only socket descriptors I receive are of value 0. This even occurs with multiple clients connecting simultaneously. I seem to be misunderstanding something to do with the behavior of accept(), or there is some bug I cannot locate in my code. Here is the code:

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

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

/* Utility for consisely killing the program. */
void abort_program(const char *error_message)
{
    fputs(error_message, stderr);
    exit(EXIT_FAILURE);
}

/* Establishes a passive listening port, returns socket descriptor. */
int setup_passive_port(int port)
{
    struct protoent *ptrp;  // pointer to a protocol table entry
    struct sockaddr_in sad; // structure to hold server's address
    int     sd;             // socket descriptor for listening

    /* Map TCP transport protocol name to protocol number. */
    if (((long int) (ptrp = getprotobyname("tcp"))) == 0) 
        abort_program("ERROR: Cannot map TCP to protocol number\n");

    /* Create a socket. */
    sd = socket(PF_INET, SOCK_STREAM, ptrp->p_proto);
    if (sd < 0) 
        abort_program("ERROR: Socket creation failed\n");

    /* Prepare the socket address structure. */
    memset((char *) &sad, 0, sizeof(sad));
    sad.sin_family = AF_INET; 
    sad.sin_addr.s_addr = INADDR_ANY;
    sad.sin_port = htons((u_short) port);

    /* Bind a local address to the socket. */
    if (bind(sd, (struct sockaddr*) &sad, sizeof(sad)) < 0)
        abort_program("ERROR: Bind failed\n");

    /* Establish passive listener socket. */
    if (listen(sd, 0) < 0)
        abort_program("ERROR: Listen failed\n");    

    return sd;
}

int main(int argc, char *argv[])
{
    struct sockaddr_in cad; // structure to hold client's address
    int     alen;           // length of address
    int     sd;             // incoming socket
    int     listener;       // listening socket

    listener = setup_passive_port(30000);

    while (1) {

        if (sd = accept(listener, (struct sockaddr*) &cad, &alen) < 0)
            abort_program("ERROR: Accept failed\n");

        printf("%d\n", sd);

    }

}

Can you help me understand why? Thanks for your consideration.

Upvotes: 1

Views: 1006

Answers (1)

BitTickler
BitTickler

Reputation: 11875

One thing you need to do is to set your alen to the sizeof(sockaddr_in) prior to calling accept(). The other is that at least clang complains about the missing brackets within your if( accept()...) line. Here the fixed up version.

telnet localhost 30000 worked as expected.

Also changed your int alen to socklen_t alen while being at it.

int main(int argc, char *argv[])
{
    struct sockaddr_in cad; // structure to hold client's address
    socklen_t     alen = sizeof(sockaddr_in);           // length of address
    int     sd;             // incoming socket
    int     listener;       // listening socket

    listener = setup_passive_port(30000);

    while (1) {

        if ((sd = accept(listener, (struct sockaddr*) &cad, &alen)) < 0)
            abort_program("ERROR: Accept failed\n");

        printf("%d\n", sd);

    }

}

Upvotes: 5

Related Questions