[Linux网络编程] 并发服务器的实现

一、并发服务器

并发服务器模型的实现主要有三种方式:

1. 多进程

2. 多线程

3. 调用fcntl将sockfd设置为非阻塞模式

二、多进程方式(参考代码C语言)

/*****************************************************
File name:并发服务器
Author:Zhengqijun    Version:1.2    Date: 2016/11/15
Description:多进程方式
*****************************************************/

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define MY_PORT 2222

int main()
{
    pid_t pid;
    int ret;
    int sockfd, sock_fd;
    char buf[1024];
    struct sockaddr_in serv_addr;
    int addrlen = sizeof(struct sockaddr);
    
    //socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0)
    {
        printf("socket is error!\n");
        exit(1);
    }

    //bind
    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port   = htons(MY_PORT);
    serv_addr.sin_addr.s_addr = inet_addr("192.168.1.122");
    if(bind(sockfd, (struct sockaddr *)(&serv_addr), addrlen) < 0)
    {
        printf("bind is error!\n");
        exit(1);
    }

    //listen
    if(listen(sockfd, 5) < 0)
    {
        printf("listen is error!\n");
        exit(1);
    }

    //accept
    while(1)
    {
        sock_fd = accept(sockfd, (struct sockaddr *)(&serv_addr), (unsigned int *)(&addrlen));
        if(sock_fd < 0)
        {
            printf("accept is error!\n");
            exit(1);
        }

        // fork ! ! !
        if((pid = fork()) == 0)
        {
            ret = recv(sock_fd, buf, sizeof(buf), 0);
            if(ret < 0)
            {
                printf("recv is error!\n");
                exit(1);
            }
            buf[ret] = '\0';
            printf("recv is %s, pid = %d\n", buf, getpid());
            close(sock_fd);
            exit(1);
        }
        else
        {
            close(sock_fd);
        }
    }

    close(sockfd);

    return 0;
}

但是多进程方式开销相对来说比较大,因此用的地方并不多。


三、多线程方式(参考代码C语言)

/*****************************************************
File name:并发服务器
Author:Zhengqijun    Version:1.3    Date: 2016/11/15
Description:多线程方式
*****************************************************/

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define MY_PORT 2222

void *pthread1(void *arg)
{
    int fd = *((int *)arg);
    int nread;
    char buf[1024];

    while((nread = read(fd, buf, sizeof(buf))) > 0)
    {
        buf[nread] = 0;
        printf("recv is %s\n", buf);
        bzero(buf, 1024);
    }

    return (void *)0;
}

void *pthread2(void *arg)
{
    int fd = *((int *)arg);
    char buf[1024];

    while(1)
    {
        printf("input a write string\n");
        scanf(" %s", buf);
        write(fd, buf, sizeof(buf));
        bzero(buf, 1024);
    }

    return (void *)0;
}

int main()
{
    int sockfd, sock_fd;
    int ret;
    struct sockaddr_in serv_addr;
    int addrlen = sizeof(struct sockaddr);
    pthread_t id;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0)
    {
        printf("socket is error!\n");
        exit(1);
    }

    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port   = htons(MY_PORT);
    serv_addr.sin_addr.s_addr = inet_addr("192.168.1.121");
    if(bind(sockfd, (struct sockaddr *)(&serv_addr), addrlen) < 0)
    {
        fprintf(stderr, "%s\n", strerror(errno));
        printf("bind is error!\n");
        exit(1);
    }

    if(listen(sockfd, 10) < 0)
    {
        printf("listen is error!\n");
        exit(1);
    }

    while(1)
    {
        sock_fd = accept(sockfd, (struct sockaddr *)(&serv_addr), (unsigned int *)(&addrlen));
        if(sock_fd < 0)
        {
            printf("accept is error!\n");
            exit(1);
        }

        pthread_create(&id, NULL, (void *)pthread1, (void *)(&sock_fd));
        pthread_create(&id, NULL, (void *)pthread2, (void *)(&sock_fd));
    }

    exit(1);
    close(sockfd);
    close(sock_fd);

    return 0;
}

你可能感兴趣的:(Linux,C)