欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

linux 多线程并发服务器(TCP)

程序员文章站 2024-02-24 10:28:22
...

linux 多线程并发服务器(TCP)

​ 所谓多线程并发服务器就是基于线程,每个客户端来了创建一个线程,由线程去处理客户端的请求。相对于多线程服务器来说,多进程服务器在创建进程时要消耗较大的系统资源,所以我们使用线程来取代进程,这样服务处理程序可以较快的创建。

​ 据统计,创建线程与创建进程要快 10100 倍,所以又把线程称为“轻量级”进程。线程与进程不同的是:一个进程内的所有线程共享相同的全局内存、全局变量等信息,这种机制又带来了同步问题。

CP多线程并发服务器处理框架:

#include"头文件"

int main()
{
    创建套接字sockfd
    绑定套接字(bind)
    监听套接字(listen)
    while1)
    {
        int connfd = accept(....);
        pthread_t thread_tid;
        pthread_create(...);
        pthread_detch(thread_tid);
    }
    close(sockfd);
    return 0;
}
//线程处理函数
void* fun(coid* arg)
{

    int connfd = (int)arg;
    fun();//处理函数
    close(connfd);
}

接下来是一个例子:

utili.h

#include <stdio.h>
#include <stdlib.h>
#include <string.h>                     
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>                  

#define PORT 8888

ser.c

#include"utili.h"


void* client_fun(void *arg)
{
    int recvlen = 0;
    char recvbuf[1024] = "";
    int connfd = (int)arg;
    while((recvlen = recv(connfd,recvbuf,sizeof(recvbuf),0))>0)
    {
        printf("recv_buf: %s\n", recvbuf);
        send(connfd, recvbuf, recvlen, 0);
    }

    printf("client closed!\n");
    close(connfd);
    return NULL;
}

int main()
{
    int sockfd;
    int log;
    int connfd;
    pthread_t thread_id;
    //chushihua 
    struct sockaddr_in server,client;
    bzero(&server,sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(PORT);
    server.sin_addr.s_addr = htonl(INADDR_ANY);

    //创建套接字
    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
        printf("socket create error\n");
    log = bind(sockfd,(struct sockaddr*)&server,sizeof(server));
    if(log < 0)
    {
        printf("bindfd error\n");
        close(sockfd);
        exit(-1);
    }

    log = listen(sockfd,20);
    if(log < 0)
    {
        printf("listen error\n");
        close(sockfd);
        exit(-1);
    }
    printf("waiting client >>>>>\n");

    while(1)
    {
        socklen_t client_len = sizeof(client);
        //accept
    connfd = accept(sockfd,(struct sockaddr*)&client,&client_len);
    if(connfd < 0)
    {
        printf("connfd error\n");
        continue;
    }
    char cli_ip[INET_ADDRSTRLEN] = "";
    inet_ntop(AF_INET, &client.sin_addr, cli_ip, INET_ADDRSTRLEN);
    printf("----------------------------------------------\n");
    printf("client ip=%s,port=%d\n", cli_ip,ntohs(client.sin_port));

    pthread_create(&thread_id,NULL,(void*)client_fun,(void*)connfd);
    pthread_detach(thread_id);//线程分离,结束时自动回收线程
    }
    close(sockfd);
    return 0;
}

cli.c

#include"utili.h"


int main()
{
    int sockfd;
    int log;
    struct sockaddr_in server;
    bzero(&server,sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(PORT);
    server.sin_addr.s_addr = htonl(INADDR_ANY);


    sockfd = socket(AF_INET,SOCK_STREAM,0);
    if(sockfd < 0)
    {
        printf("sockfd error\n");
        exit(-1);
    }
    log = connect(sockfd,(struct sockaddr*)&server,sizeof(server));
    if(log < 0)
    {
        printf("connect error\n");
        close(sockfd);
        exit(-1);
    }

    char sendbuf[1024];
    char recvbuf[1024];
    while(1)
    {
        fgets(sendbuf,sizeof(sendbuf),stdin);
        send(sockfd,sendbuf,strlen(sendbuf),0);
        recv(sockfd,recvbuf,sizeof(recvbuf),0);
        fputs(recvbuf,stdout);
        memset(sendbuf, 0, sizeof(sendbuf));
        memset(recvbuf, 0, sizeof(recvbuf));
    }
    close(sockfd);
    return 0;
}