How to fix "Error reading from socket - bad file descriptor" while in thread on Linux using C?

geckiss

I am setting up a server-client application(chat) and i have encountered a problem with sockets/threads. Both server and client run on Linux.

I want the server to be able to serve multiple users, and to do it I want to use threads from pthread.h, so every logged user has his own thread.

This is the server: main.c

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "manazerUctov.h"

int pocetVlakienZOP = 0;

int main(int argc, char *argv[])
{
    pthread_t* vlaknaZiadosti = 
    (pthread_t*)malloc(sizeof(pthread_t)*POCET_UZIVATELOV);

    int sockfd, newsockfd;
    socklen_t cli_len;
    struct sockaddr_in serv_addr, cli_addr;
    int n;

    // Program
    if (argc < 2) {
        fprintf(stderr, "usage %s port\n", argv[0]);
        return 1;
    }

    bzero((char*) &serv_addr, sizeof (serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(atoi(argv[1]));

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        perror("Error creating socket\n");
        return 1;
    }
    printf("Socket OK\n");

    if (bind(sockfd, (struct sockaddr*) &serv_addr, sizeof (serv_addr)) < 0) {
        perror("Error binding socket address\n");
        return 2;
    }
    printf("Bind OK\n");

    listen(sockfd, 5);
    while (1) {

        cli_len = sizeof (cli_addr);

        newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &cli_len);
        if (newsockfd < 0) {
            perror("ERROR on accept\n");
            return 3;
        }
        printf("Accept OK\n");
        client_data* cdata = (client_data*) malloc(sizeof (client_data));
        cdata->socket = newsockfd;

        pthread_t vlakno;
        vlaknaZiadosti[pocetVlakienZOP++] = vlakno;
        pthread_create(&vlakno, NULL, &serveClient, &cdata);
    }

    close(sockfd);
    return 0;
}

manazerUctov.h:

#ifndef MANAZERUCTOV_H
#define MANAZERUCTOV_H

#ifndef POCET_UZIVATELOV
#define POCET_UZIVATELOV 256
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
    char *buffer;
    char* msg;                         
    int socket;
} client_data;

void* serveClient(void* pdata);

#ifdef __cplusplus
}
#endif

#endif /* MANAZERUCTOV_H */

manazerUctov.c Here, the read function is giving error:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "manazerUctov.h"

void* serveClient(void *pdata) {
    char buffer[256];
    client_data* client = (client_data*)pdata;
    bzero(buffer, 256);

    int n = read(client->socket, buffer, 255);
    if (n < 0) {
        perror("Error reading from socket\n");
        return NULL;
    }

    printf("Read from socket\n");
    close(client->socket);
}

When the client sends socket, the server accepts it and creates a thread, but I get Error reading from socket: bad file descriptor. And the program is stuck, it won't even exit. And as far as I am concerned the sockets aren't closed yet. Before I implemented threads, reading from sockets worked correctly.

EDIT: Original code is 500 lines long, so I trimmed it and the former error was no more, although another error was &cdata in pthread_create . Removing & solved the problem in both trimmed and original code and server is working.

Craig Estey

Your pthread_create function call is incorrect.

This passes a pointer to the client_data pointer and not what the pointer points to:

pthread_create(&my_thread, NULL, &my_function, &cdata);

What you want is:

pthread_create(&my_thread, NULL, &my_function, cdata);

So, instead of getting cdata->socket, you'll get the lower 32 bits of the pointer value as your file descriptor.


Some additional notes:

Because you have a loop scoped pthread_t my_thread;, this disappears on each iteration of the loop, so the main thread won't be able to do a pthread_join on it.

So, when your thread function exits, it will be in an unjoined (i.e. zombie) state.

Also, on each iteration, each pthread_create call may point to my_thread at the same address. I'm not sure what effect this will have on other thread primitives, but I'd be wary.

You may want to add the pthread_t mythread; to your allocated struct. That way, it is guaranteed to have a unique address. And, the main thread can keep track of the structs it has allocated.

Another way to deal with this is to have your thread function do a pthread_detach at the top [or add the appropriate attributes to the pthread_create call]

This may be easier cleaner.

Also, be sure that your thread function closes its socket and does a free on the struct pointer just before exiting.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to fix the image while scrolling using JavaScript?

How to fix ZeroDivisionError while using uncertainties package?

How to fix "MaskedArrayFutureWarning" while using matplotlib?

How to fix WHILE directive when using GCC?

How to fix show method while using MetroMessageBox

How to fix screen overlap and top left zoom of HD external monitors while using 4k primary Linux Ubuntu 20?

How to pause a thread while continue others thread in C# UWP

How to fix the next thread to be more correct? Using Pthread

Is there a way to fix text trailing while using the LinearGradientBrush function in C#?

How to fix a cross-thread exception in C#?

How to fix "Activated Event Time Duration Thread Exception" in C#?

How to fix while loop?

How to fix Error: listen EADDRINUSE while using nodejs?

Chrome is crashing while image upload using selenium, How to fix it?

How to fix "Slim Application Error" error while using lampp to host

How to change the pod if I have to fix something while using cocoapods

How to fix DirectoryNotFoundException while using Process in Web App

How to fix "LPVOID: unknown size" error while using the CreateRemoteThread API?

How to fix Py4JJavaError while using .toPandas() function?

How to fix 500 internal server error while using Django and React

How to fix InvalidCastException while using JsonConverter for an IList of Interfaces?

How to Fix a Run-Time Error While Using For Each Loop

How to fix StackOverflow error while using Quicksort for big arrays?

Error while fetching record using thread in c#

How can I fix "Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value" in Swift

How to fix Segmentation Fault while trying to do RPN in C

How to fix 'Segmentation fault' while redirecting input in C

How can I clear portion of what is typed into the prompt while working on Linux and using C-shell?

How to stop recvfrom() from blocking while using in threads with UDP server in C linux?