多线程实现高并发服务器

/*
    多线程实现并发服务器
        主线程负责接收
        子线程负责处理

*/

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

struct sockInfo{
    int cfd, cnt;
    pthread_t tid;
    struct sockaddr_in client_addr;
};

struct sockInfo info_array[128];

void *callback(void *arg)
{
    int id = *(int *) arg;
    char clientIP[16];
    inet_ntop(AF_INET, (void *)&info_array[id].client_addr.sin_addr.s_addr, clientIP, sizeof(clientIP));
    unsigned short clientPORT = ntohs(info_array[id].client_addr.sin_port);

    printf("client ip is %s, port is %d\n", clientIP, clientPORT);
    char recvBuf[1024] = {0};
    int recvlen = read(info_array[id].cfd, recvBuf, sizeof(recvBuf));
    if(recvlen == -1)
    {
        perror("read");
        exit(-1);
    }
    else if(recvlen == 0)
    {
        printf("客户端断开连接······\n");
        // 如果循环发送接收,这个地方要加 break
    }
    else
    {
        printf("recv client data: %s\n", recvBuf);
    }


    // 给客户端发送数据
    char *data = "hello, i am server";

    int len = write(cfd, data, strlen(data));
    if(len == -1)
    {
        perror("write");
        exit(-1);
    }
    return NULL;
}


int main()
{

    
    
    sigaction(SIGCHLD, &act, NULL);

    int lfd = socket(AF_INET, SOCK_STREAM, 0);
    if(lfd == -1)
    {
        perror("socket");
        exit(-1);
    }

    char *temp = "192.168.248.128";
    int inet_ip;
    struct sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    inet_pton(AF_INET, temp, (void *) &inet_ip);
    saddr.sin_addr.s_addr = inet_ip;
    saddr.sin_port = htons(9999);
    int ret = bind(lfd, (struct sockaddr *) &saddr, sizeof(saddr));
    if(ret == -1)
    {
        perror("bind");
        exit(-1);
    }
    ret = listen(lfd, 5);
    if(ret == -1)
    {
        perror("listen");
        exit(-1);
    }
    int info_cnt = 0;
    while(1)
    {
        struct sockaddr_in client_addr;
        int client_addr_len = sizeof(client_addr);
        int cfd = accept(lfd, (struct sockaddr *) &client_addr, (void *) &client_addr_len);
        if(cfd == -1)
        {
            if(errno == EINTR)
                continue;
            perror("accept");
            exit(-1);
        }
        // struct sockInfo info;
        // info.cfd = cfd;
        // // info.client_addr = client_addr; // 结构体不能直接赋值结构体
        // memcpy(info.client_addr, client_addr, sizeof(client_addr));
        info_array[info_cnt].cfd = cfd;
        memcpy(info_array[info_cnt].client_addr, client_addr, sizeof(client_addr));
        info_array[info_cnt].cnt = info_cnt;

        pthread_create(&info_array[info_cnt].tid, NULL, callback, (void *) &info_array[info_cnt].cnt);
        pthread_detach(new_thread);
        info_cnt++;
        if(info_cnt == sizeof(info_array)) / sizeof(info_array[0]);
            break;
    }
    sleep(1);

    for(int i = 0; i < info_cnt; i++)
        close(info_array[i]->cfd);
    close(lfd);



    return 0;
}

 

posted @ 2023-05-11 11:23  WTSRUVF  阅读(23)  评论(0编辑  收藏  举报