简体   繁体   中英

C Socket Code Generates ERRNO 24 Messages

I have written a C program that I hope to use as a simple TCP/IP based service. The program has to open a listening TCP socket. Whenever someone writes to the socket, my program has to read the message, do a little processing, then send a different message back. The program has to run forever.

The program compiles and runs. (I'm using gcc 7.4.0) Trouble is, after a couple thousand messages are successfully processed without any problems, the program starts printing this:

...
 Connection FAILED :: Value of errno: 24
 Connection FAILED :: Value of errno: 24
 Connection FAILED :: Value of errno: 24
 Connection FAILED :: Value of errno: 24
...

Errno 24 means “too many file descriptors open,” which makes me wonder if my program is allocating something (sockets? memory?) and not properly deallocating it later. But I can't spot where I'm going wrong.

Let me show you my code. I followed a tutorial I liked, where they gathered all the relevant socket info in one struct:

typedef struct{
        int sock;
        struct sockaddr address;
        socklen_t addr_len;
} connection_t;

The main() sets up the socket, then listens to it in an infinite loop to listen:

int main(int argc, char ** argv) {
        int             sock = -1;
        struct          sockaddr_in address;
        int             port = 12345;
        connection_t*   connection;


        // Create the listening socket
        sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (sock <= 0){
                fprintf(stderr, "%s: error: cannot create socket\n", argv[0]);
                return -3;
        }

        // Bind socket to port
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = INADDR_ANY;
        address.sin_port = htons(port);
        if (bind(sock, (struct sockaddr *)&address, sizeof(struct sockaddr_in)) < 0){
                fprintf(stderr, "%s: error: cannot bind socket to port %d\n", argv[0], port);
                return -4;
        }

        // Listen on the port
        if (listen(sock, 5) < 0){
                fprintf(stderr, "%s: error: cannot listen on port\n", argv[0]);
                return -5;
        }

        // We're ready to go...!
        printf("%s: ready and listening\n", argv[0]);

        while (1){
                // Accept incoming connections
                connection = (connection_t *)malloc(sizeof(connection_t));
                connection->addr_len = 20;

                connection->sock = accept(sock, &connection->address, &connection->addr_len);

                if (connection->sock <= 0){
                        // ***********************************************
                        // ***  This is where the error happens!
                        printf("Connection FAILED :: Value of errno: %d\n ", errno);
                        // ***********************************************
                }
                else{
                        printf("SERVER...  New Msg received...\n");
                        readMsgAndReply( connection );
                }
                free(connection);
        }
        return 0;
}

You'll note that I get my “Connection FAILED” message when accept() cannot successfully accept a new, incoming connection – I wish I knew why.

If accept() is successful, my code calls readMsgAndReply():

void readMsgAndReply( connection* conn ){

        char* buffer;
        char* reply = "Your Msg was received!";
        int ret, len, replyLen;
        long addr = 0;

        // First call to read() measures the length of the sent message
        ret = read(conn->sock, &len, sizeof(int));
        if( ret < 0 ){
                printf( "***readMsgAndReply() ERROR:  read() error\n" );
        }
        if( len > 0 ){
                addr = (long)((struct sockaddr_in *)&conn->address)->sin_addr.s_addr;
                buffer = (char *)malloc((len+1)*sizeof(char));
                buffer[len] = 0;

                // Second call to read() actually reads the message from the socket
                ret = read(conn->sock, buffer, len);
                if( ret < 0 ){
                        printf( "***readMsgAndReply() ERROR:  ret < 0\n");
                }
                else{
                        printf("***readMsgAndReply() message size :: %d\n",  len);
                        printf("***readMsgAndReply() is           :: \"%s\"\n", buffer);
                }

                // write reply message back to the client
                replyLen = write(conn->sock, reply, strlen(reply));
                if(replyLen > 0)
                        printf("===>  Reply written, %d bytes sent!\n", replyLen);
                else
                        printf("--->  No reply written\n");

                free(buffer);
        }
}

There you have it. This code works beautifully for the first several thousand received messages, then spits out ERRNO 24. Anyone see what I'm doing wrong?

Before exiting function readMsgAndReply you need to close socket.

 close(connection->sock);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM