After the first child thread exits, the process ends in Linux socket

Viewed 37

After the first child thread exits, the process ends in Linux socket. Please point the error,thanks. After I close the first client thread, the main process close,too. I don't know how to modify the code. The following is my whole codes.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/signal.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>

#define BUF_SIZE 1024
#define CONNECT_INFO 100
#define CLIENT_SIZE 100

int serv_port = 20000; 

pthread_mutex_t mutex; 

int clintQueue[CLIENT_SIZE]; 
int front = 0, rear = 0;     

void error_handle(char *message);
void *read_func(void *clnt_sock);
int send_message(int socketFd, char *message, int len);

void error_handle(char *message)
{
    perror(message);
    exit(-1);
}

int send_message(int socketFd, char *message, int len)
{
    pthread_mutex_lock(&mutex);
    int ret = write(socketFd, message, len);
    if (ret <= 0)
    {
        perror("write error");
    }
    pthread_mutex_unlock(&mutex);
    return ret <= 0 ? 0 : 1;
}

void *read_func(void *arg)
{
    // pthread_detach(pthread_self());
    int clnt_sock = *(int *)arg;
    char buf[BUF_SIZE];
    int message_len;
    while ((message_len = read(clnt_sock, buf, BUF_SIZE)) != 0)
    {
        buf[message_len] = 0;
        printf("%s", buf);
        send_message(clnt_sock, buf, message_len - 1);
        memset(buf, 0, BUF_SIZE);
    }
    pthread_mutex_lock(&mutex);
    printf("client %d[queue is %d]log out\n", clnt_sock, clintQueue[front]);
    front++;
    pthread_mutex_unlock(&mutex);
    close(clnt_sock);
    return NULL;
}

int main(int argc, char *argv[])
{
    
    char clientInfo[CONNECT_INFO];
    int serv_sock, clnt_sock;
    socklen_t clnt_addr_len;
    pthread_t read_id; //线程id
    struct sockaddr_in serv_addr, clnt_addr;
    pthread_mutex_init(&mutex, NULL); 

    serv_sock = socket(PF_INET, SOCK_STREAM, 0);
    if (serv_sock < 0)
    {
        perror("serv_sock create failed!");
    }
    memset(&serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(serv_port);
    serv_addr.sin_addr.s_addr = INADDR_ANY;
   
    if (bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    {
        error_handle("bind fail");
    }
    else
    {
        puts("bind success");
    }

    if (listen(serv_sock, CLIENT_SIZE) < 0)
    {
        error_handle("listen fail");
    }
    else
    {
        puts("listen success");
    }

    while (1)
    {
        clnt_addr_len = sizeof(clnt_addr);
        clnt_sock = accept(serv_sock, (struct sockaddr *)&clnt_addr, &clnt_addr_len);
        if (clnt_sock < 0)
        {
            puts("clnt_sock < 0");
            close(clnt_sock);
        }
       
        if (front == (rear + 1) % CLIENT_SIZE)
        {
            puts("client queue has flowed, connect failed");
            close(clnt_sock);
        }
        else
        {
            memset(clientInfo, 0, sizeof(clientInfo));
            pthread_mutex_lock(&mutex);
            clintQueue[rear++] = clnt_sock;
            pthread_mutex_unlock(&mutex);
            // debug rear
            printf("%d\n", rear);
            puts("client queue add");

            sprintf(clientInfo, "clientInfo[fd:%d, ip:%s, port:%d] has connected!", clnt_sock, inet_ntoa(clnt_addr.sin_addr), ntohs(clnt_addr.sin_port));
            puts(clientInfo);

            pthread_create(&read_id, NULL, read_func, (void *)&clnt_sock);
            pthread_detach(read_id);
            printf("thread %ld create success!\n", (pthread_t)read_id);
           
        }
    }
    close(serv_sock);
    pthread_mutex_destroy(&mutex);
    return 0;
}

I want to use a main thread to control the connection, and the child threads to handle sending and receiving

1 Answers

On my computer, the application seems to behave fine:


florian@florian-desktop:~$ ./a.out 
bind success
listen success
1
client queue add
clientInfo[fd:4, ip:127.0.0.1, port:33730] has connected!
thread 140353384478272 create success!
client 4[queue is 4]log out
2
client queue add
clientInfo[fd:5, ip:127.0.0.1, port:33732] has connected!
thread 140353384478272 create success!
this is a test
client 5[queue is 5]log out

I connected two telnet sessions to the application. I killed the first telnet immediatelly and the second telnet after sending out the message "this is a test".

Related