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

来源:互联网 发布:js获取当前手机型号 编辑:程序博客网 时间:2024/04/30 04:11

一、并发服务器

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

1. 多进程

2. 多线程

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

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

/*****************************************************File name:并发服务器Author:Zhengqijun    Version:1.2    Date: 2016/11/15Description:多进程方式*****************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <sys/types.h>#include <unistd.h>#include <arpa/inet.h>#include <netinet/in.h>#define MY_PORT 2222int 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/15Description:多线程方式*****************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#include <pthread.h>#include <errno.h>#define MY_PORT 2222void *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;}

0 0
原创粉丝点击