qaqc 2022-05-01 21:02 采纳率: 0%
浏览 19

linux socket编程中,第一个子线程退出后,进程随之结束。请指正其中的错误

问题相关代码
#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]; //客户端fd环形队列
int front = 0, rear = 0;     //客户端fd队列起始状态

void error_handle(char *message);
void *read_func(void *clnt_sock);
int send_message(int socketFd, char *message, int len);
/**
 * @brief 打印错误信息
 *
 * @param message
 */
void error_handle(char *message)
{
    perror(message);
    exit(-1);
}
/**
 * @brief 发送消息,成功返回1
 *
 * @param socketFd
 * @param message
 * @param len
 * @return int
 */
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;
}

/**
 * @brief 子线程读取客户端发送数据
 *
 * @param arg:客户端sockfd
 * @return void*
 */
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;
}

void *write_func(void *arg)
{
}

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;
    // bind
    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));
            //客户端fd入队
            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;
}
  • 写回答

1条回答 默认 最新

  • 赵4老师 2022-05-01 21:54
    关注

    加join?

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 5月1日

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料