linux网络编程-----几种服务器模型及io多路复用函数

libevent实现了对io多路复用函数的封装,复习一下linux下的io复用函数,select,poll,epoll

在c/s模型中,要处理多个客户端的请求以达到并发处理的效果,有以下几种方法

  • 主线程accept,多线程处理,为每一个客户端开一个线程
  • 主进程accept,多进程处理,为每一个客户端开一个进程
  • 线程池/进程池,将程序执行过程中线程/进程的创建销毁开销放在程序一开始执行时进行,进一步可以动态改变池中线程/进程个数
  • io多路复用函数,单线程模式

多线程模式的服务器模型大体如下

//server.cpp
#include <iostream>

#include <cerrno>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <unistd.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#include <pthread.h>


void* process_client(void* arg);

int main()
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0)
    {
        std::cerr << "socket error" << std::endl;
        return -1;
    }

    struct sockaddr_in servaddr;
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(8080);
    servaddr.sin_addr.s_addr = INADDR_ANY;

    if(bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
    {
        close(sockfd);
        std::cerr << "bind error" << std::endl;
        return -1;
    }

    if(listen(sockfd, 10) < 0)
    {
        close(sockfd);
        std::cerr << "listen error" << std::endl;
        return -1;
    }

    struct sockaddr_in addr;
    bzero(&addr, sizeof(addr));
    socklen_t len = sizeof(addr);
    while(true)
    {
        /* 主线程接受客户端请求,每一个子线程处理一个服务器与客户端的交互 */
        int fd = accept(sockfd, (struct sockaddr*)&addr, &len);

        pthread_t tid;
        pthread_create(&tid, NULL, process_client, (void*)&fd);
        pthread_detach(tid);
    }

    close(sockfd);

    return 0;
}


void *process_client(void *arg)
{
    int fd = *static_cast<int *>(arg);

    char reply[] = "server has receive your message";
    char msg[4096];
    /* 每个线程一个循环 */
    while(true)
    {
        bzero(msg, sizeof(msg));
        int ret = recv(fd, msg, sizeof(msg), 0);
        if(ret < 0)
        {
            continue;
        }
        else if(ret == 0)
        {  std::cout << "close connection with client " << fd << std::endl;
            close(fd);
            pthread_exit(NULL);
            break;
        }
        else
        {
            msg[ret] = '\0';
            std::cout << "receive from client " << fd << " : " << msg << std::endl;

            ret = send(fd, reply, strlen(reply), MSG_NOSIGNAL);
            if(ret < 0)
            {
                continue;
            }
            else if(ret == 0)
            {
                std::cout << "close connection with client " << fd << std::endl;
                close(fd);
                pthread_exit(NULL);
                break;
            }
        }
    }

}
//client.cpp
#include <iostream>
#include <string>

#include <cerrno>
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值