日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

循环服务器,并发服务器模型以及I/O多路转接模型

發(fā)布時(shí)間:2023/11/30 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 循环服务器,并发服务器模型以及I/O多路转接模型 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

https://blog.csdn.net/xinianbuxiu/article/details/53455784

一、基于TCP/IP協(xié)議的基本循環(huán)服務(wù)器

tcp_server.c

?

  • #include <stdio.h>

  • #include <stdlib.h>

  • #include <string.h>

  • ?
  • #include <sys/types.h>

  • #include <sys/socket.h>

  • #include <sys/stat.h>

  • #include <netdb.h>

  • ?
  • #define PORT 3333

  • #define MAX_SIZE 1024

  • ?
  • int main()

  • {

  • int sockfd;

  • int new_fd;

  • ?
  • struct sockaddr_in server_addr;

  • struct sockaddr_in client_addr;

  • ?
  • int n_read;

  • int ser_size;

  • int opt = 1;

  • ?
  • char buffer[MAX_SIZE];

  • ?
  • if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)

  • {

  • perror("socket error!\n");

  • exit(1);

  • }

  • ?
  • printf("socket success.............!\n");

  • ?
  • if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)) < 0)

  • {

  • perror("set socket option error!\n");

  • exit(1);

  • }

  • ?
  • bzero(&server_addr,0);

  • server_addr.sin_family = AF_INET;

  • server_addr.sin_port = htons(PORT);

  • server_addr.sin_addr.s_addr = inet_addr("192.168.1.10");

  • ?
  • if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof server_addr) < 0)

  • {

  • perror("bind error!\n");

  • exit(1);

  • }

  • ?
  • printf("bind success.............!\n");

  • listen(sockfd,5);

  • ?
  • printf("listen success.............!\n");

  • ?
  • printf("accepting..................!\n");

  • ?
  • while(1)

  • {

  • ser_size = sizeof client_addr;

  • ?
  • if((new_fd = accept(sockfd,(struct sockaddr *)&client_addr,&ser_size)) < 0)

  • {

  • perror("accept error!\n");

  • exit(1);

  • }

  • ?
  • printf("accept success.................!\n");

  • ?
  • //read\recv

  • ?
  • printf("reading............!\n");

  • n_read = read(new_fd,buffer,sizeof(buffer));

  • ?
  • if(n_read < 0)

  • {

  • perror("read client msg error!\n");

  • exit(1);

  • }

  • ?
  • buffer[n_read] = '\0';

  • ?
  • printf("recv msg = %s\n",buffer);

  • }

  • ?
  • return 0;

  • }

  • tcp_client.c

    ?

  • #include <stdio.h>

  • #include <string.h>

  • #include <stdlib.h>

  • ?
  • #include <sys/types.h>

  • #include <sys/socket.h>

  • #include <netdb.h>

  • ?
  • #define PORT 3333

  • #define MAX_SIZE 1024

  • ?
  • int main(int argc, char *argv[])

  • {

  • if(argc != 2)

  • {

  • printf("Please input server ip!\n");

  • exit(1);

  • }

  • ?
  • int sockfd;

  • int n_write;

  • ?
  • struct sockaddr_in server_addr;

  • ?
  • char buffer[MAX_SIZE];

  • ?
  • if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)

  • {

  • perror("client socket error!\n");

  • exit(1);

  • }

  • ?
  • bzero(&server_addr,0);

  • ?
  • server_addr.sin_family = AF_INET;

  • server_addr.sin_port = htons(PORT);

  • server_addr.sin_addr.s_addr = inet_addr(argv[1]);

  • ?
  • if(connect(sockfd,(struct sockaddr *)&server_addr,sizeof server_addr) < 0)

  • {

  • perror("connect server error!\n");

  • exit(1);

  • }

  • ?
  • while(1)

  • {

  • memset(buffer,0,sizeof(buffer));

  • printf("Please input send msg:\n");

  • gets(buffer);

  • ?
  • n_write = write(sockfd,buffer,strlen(buffer));

  • ?
  • if(n_write == -1)

  • {

  • perror("send to server msg error!\n");

  • exit(1);

  • }

  • }

  • ?
  • return 0;

  • }

  • 循環(huán)服務(wù)器能不斷地接收客戶(hù)端發(fā)送過(guò)來(lái)的信息,但是在面對(duì)多個(gè)客戶(hù)端時(shí),服務(wù)器必須等待第一個(gè)客戶(hù)端發(fā)送信息才能接受其他客戶(hù)端發(fā)來(lái)的信息。

    由此,我們使用并發(fā)服務(wù)器,通過(guò)創(chuàng)建子進(jìn)程,使得多個(gè)客戶(hù)端能隨時(shí)發(fā)信息給服務(wù)器

    并發(fā)服務(wù)器:

    ?

  • #include <stdio.h>

  • #include <stdlib.h>

  • #include <string.h>

  • ?
  • #include <sys/types.h>

  • #include <sys/socket.h>

  • #include <sys/stat.h>

  • #include <netdb.h>

  • ?
  • #define PORT 3333

  • #define MAX_SIZE 1024

  • ?
  • void * read_msg(void *arg)

  • {

  • int n_read;

  • ?
  • int new_fd = *((int *)arg);

  • ?
  • char buffer[MAX_SIZE];

  • ?
  • printf("new_fd = %d\n",new_fd);

  • ?
  • while(1)

  • {

  • memset(buffer,0,sizeof(buffer));

  • ?
  • n_read = read(new_fd,buffer,sizeof(buffer));

  • ?
  • if(n_read < 0)

  • {

  • perror("recv client msg error!\n");

  • exit(1);

  • }

  • ?
  • if(n_read == 0)

  • {

  • printf("client is close!!\n");

  • close(new_fd);

  • pthread_exit(NULL);

  • }

  • ?
  • buffer[n_read] = '\0';

  • ?
  • printf("recv msg:%s\n",buffer);

  • }

  • }

  • ?
  • int main()

  • {

  • int sockfd;

  • int new_fd;

  • ?
  • struct sockaddr_in server_addr;

  • struct sockaddr_in client_addr;

  • ?
  • int n_read;

  • int ser_size;

  • int opt = 1;

  • ?
  • char buffer[MAX_SIZE];

  • ?
  • pthread_t id;

  • ?
  • if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)

  • {

  • perror("socket error!\n");

  • exit(1);

  • }

  • ?
  • printf("socket success.............!\n");

  • ?
  • if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)) < 0)

  • {

  • perror("set socket option error!\n");

  • exit(1);

  • }

  • ?
  • bzero(&server_addr,0);

  • server_addr.sin_family = AF_INET;

  • server_addr.sin_port = htons(PORT);

  • server_addr.sin_addr.s_addr = inet_addr("192.168.1.10");

  • ?
  • if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof server_addr) < 0)

  • {

  • perror("bind error!\n");

  • exit(1);

  • }

  • ?
  • printf("bind success.............!\n");

  • listen(sockfd,5);

  • ?
  • printf("listen success.............!\n");

  • ?
  • printf("accepting..................!\n");

  • ?
  • while(1)

  • {

  • ser_size = sizeof client_addr;

  • ?
  • if((new_fd = accept(sockfd,(struct sockaddr *)&client_addr,&ser_size)) < 0)

  • {

  • perror("accept error!\n");

  • exit(1);

  • }

  • ?
  • printf("accept success.................!\n");

  • ?
  • pthread_create(&id,NULL,read_msg,&new_fd);

  • }

  • ?
  • return 0;

  • }

  • 并發(fā)客戶(hù)端:

    ?

  • #include <stdio.h>

  • #include <string.h>

  • #include <stdlib.h>

  • ?
  • #include <sys/types.h>

  • #include <sys/socket.h>

  • #include <netdb.h>

  • ?
  • #define PORT 3333

  • #define MAX_SIZE 1024

  • ?
  • int main(int argc, char *argv[])

  • {

  • if(argc != 2)

  • {

  • printf("Please input server ip!\n");

  • exit(1);

  • }

  • ?
  • int sockfd;

  • int n_write;

  • ?
  • struct sockaddr_in server_addr;

  • ?
  • char buffer[MAX_SIZE];

  • ?
  • if((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)

  • {

  • perror("client socket error!\n");

  • exit(1);

  • }

  • ?
  • bzero(&server_addr,0);

  • ?
  • server_addr.sin_family = AF_INET;

  • server_addr.sin_port = htons(PORT);

  • server_addr.sin_addr.s_addr = inet_addr(argv[1]);

  • ?
  • if(connect(sockfd,(struct sockaddr *)&server_addr,sizeof server_addr) < 0)

  • {

  • perror("connect server error!\n");

  • exit(1);

  • }

  • ?
  • while(1)

  • {

  • memset(buffer,0,sizeof(buffer));

  • printf("Please input send msg:\n");

  • gets(buffer);

  • ?
  • n_write = write(sockfd,buffer,strlen(buffer));

  • ?
  • if(n_write == -1)

  • {

  • perror("send to server msg error!\n");

  • exit(1);

  • }

  • }

  • ?
  • return 0;

  • }


  • 并發(fā)服務(wù)器模型的缺點(diǎn)是:客戶(hù)端不再和服務(wù)器交互時(shí),其多線程仍在工作,比較耗費(fèi)CPU 的資源。

    I/O多路轉(zhuǎn)接模型:

    利用一個(gè)“監(jiān)聽(tīng)者”,當(dāng)有客戶(hù)端發(fā)出連接請(qǐng)求及客戶(hù)端發(fā)送信息時(shí),才會(huì)和服務(wù)器連接。

    服務(wù)器代碼:

    ?

  • #include <stdlib.h>

  • #include <stdio.h>

  • #include <errno.h>

  • #include <string.h>

  • #include <netdb.h>

  • #include <sys/types.h>

  • #include <netinet/in.h>

  • #include <sys/socket.h>

  • #include<unistd.h>

  • #include<arpa/inet.h>

  • #include<ctype.h>

  • ?
  • ?
  • #define portnumber 8000

  • ?
  • #define MAX_LINE 80

  • ?
  • ?
  • ?
  • int main(void)

  • {

  • int lfd;

  • int cfd;

  • int sfd;

  • int rdy;

  • ?
  • struct sockaddr_in sin;

  • struct sockaddr_in cin;

  • ?
  • int client[FD_SETSIZE];

  • ?
  • int maxi;

  • int maxfd;

  • ?
  • fd_set rset;

  • fd_set allset;

  • ?
  • socklen_t addr_len;

  • ?
  • char buffer[MAX_LINE];

  • ?
  • int i;

  • int n;

  • int len;

  • int opt = 1;

  • ?
  • char addr_p[20];

  • ?
  • ?
  • bzero(&sin,sizeof(struct sockaddr_in));

  • sin.sin_family=AF_INET;

  • sin.sin_addr.s_addr=htonl(INADDR_ANY);

  • sin.sin_port=htons(portnumber);

  • ?
  • ?
  • if((lfd=socket(AF_INET,SOCK_STREAM,0))==-1)

  • {

  • fprintf(stderr,"Socket error:%s\n\a",strerror(errno));

  • exit(1);

  • }

  • printf("socket!\n");

  • ?
  • setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

  • ?
  • ?
  • if(bind(lfd,(struct sockaddr *)(&sin),sizeof(struct sockaddr))==-1)

  • {

  • fprintf(stderr,"Bind error:%s\n\a",strerror(errno));

  • exit(1);

  • }

  • printf("bind!\n");

  • ?
  • ?
  • if(listen(lfd,20)==-1)

  • {

  • fprintf(stderr,"Listen error:%s\n\a",strerror(errno));

  • exit(1);

  • }

  • printf("listen!\n");

  • printf("Accepting connections .......\n");

  • ?
  • maxfd = lfd;

  • maxi = -1;

  • ?
  • ?
  • for(i = 0;i < FD_SETSIZE;i++)

  • {

  • client[i] = -1;

  • }

  • FD_ZERO(&allset);

  • FD_SET(lfd,&allset);

  • ?
  • ?
  • ?
  • while(1)

  • {

  • rset = allset;

  • printf("selecting!\n");

  • ?
  • rdy = select(maxfd + 1, &rset, NULL, NULL, NULL);

  • ?
  • printf("selected!\n");

  • if(FD_ISSET(lfd, &rset))

  • {

  • ?
  • addr_len = sizeof(sin);

  • printf("accepting!\n");

  • ?
  • if((cfd=accept(lfd,(struct sockaddr *)(&cin),&addr_len))==-1)

  • {

  • fprintf(stderr,"Accept error:%s\n\a",strerror(errno));

  • exit(1);

  • }

  • printf("accepted!\n");

  • ?
  • ?
  • ?
  • for(i = 0; i<FD_SETSIZE; i++)

  • { //printf("%d\t",client[i]);

  • if(client[i] <= 0)

  • {

  • client[i] = cfd;

  • break;

  • }

  • }

  • ?
  • ?
  • if(i == FD_SETSIZE)

  • {

  • printf("too many clients");

  • exit(1);

  • }

  • ?
  • FD_SET(cfd, &allset);

  • ?
  • if(cfd > maxfd)

  • {

  • maxfd = cfd;

  • }

  • ?
  • if(i > maxi)

  • {

  • maxi = i;

  • }

  • ?
  • if(--rdy <= 0)

  • {

  • continue;

  • }

  • ?
  • }

  • ?
  • for(i = 0;i< FD_SETSIZE;i++)

  • {

  • if((sfd = client[i]) < 0)

  • {

  • continue;

  • }

  • ?
  • if(FD_ISSET(sfd, &rset))

  • {

  • printf("reading!\n");

  • n = read(sfd,buffer,MAX_LINE);

  • printf("%s\n",buffer);

  • printf("read!\n");

  • if(n == 0)

  • {

  • printf("the other side has been closed. \n");

  • fflush(stdout);

  • close(sfd);

  • ?
  • FD_CLR(sfd, &allset);

  • client[i] = -1;

  • }

  • ?
  • else

  • {

  • ?
  • inet_ntop(AF_INET, &cin.sin_addr, addr_p, sizeof(addr_p));

  • addr_p[strlen(addr_p)] = '\0';

  • ?
  • ?
  • printf("Client Ip is %s, port is %d\n",addr_p,ntohs(cin.sin_port));

  • ?
  • ?
  • ?
  • if(n == 1)

  • {

  • exit(1);

  • }

  • }

  • ?
  • ?
  • if(--rdy <= 0)

  • {

  • break;

  • ?
  • ?
  • }

  • }

  • ?
  • }

  • ?
  • close(lfd);

  • return 0;

  • }

  • 多路轉(zhuǎn)接客戶(hù)端:

    ?

  • #include <stdlib.h>

  • #include <stdio.h>

  • #include <errno.h>

  • #include <string.h>

  • #include <netdb.h>

  • #include <sys/types.h>

  • #include <netinet/in.h>

  • #include <sys/socket.h>

  • ?
  • #define portnumber 8000

  • ?
  • int main(int argc, char *argv[])

  • {

  • int nbytes;

  • int sockfd;

  • char buffer[80];

  • char buffer_2[80];

  • struct sockaddr_in server_addr;

  • struct hostent *host;

  • ?
  • if(argc!=2)

  • {

  • fprintf(stderr,"Usage:%s hostname \a\n",argv[0]);

  • exit(1);

  • }

  • ?
  • if((host=gethostbyname(argv[1]))==NULL)

  • {

  • fprintf(stderr,"Gethostname error\n");

  • exit(1);

  • }

  • ?
  • ?
  • if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) // AF_INET:Internet;SOCK_STREAM:TCP

  • {

  • fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));

  • exit(1);

  • }

  • ?
  • ?
  • bzero(&server_addr,sizeof(server_addr)); //

  • server_addr.sin_family=AF_INET;

  • server_addr.sin_port=htons(portnumber);

  • server_addr.sin_addr = *((struct in_addr *)host->h_addr);//址

  • ?
  • ?
  • if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)

  • {

  • fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));

  • exit(1);

  • }

  • ?
  • while(1){

  • ?
  • printf("Please input char:\n");

  • ?
  • ?
  • fgets(buffer,1024,stdin);

  • write(sockfd,buffer,strlen(buffer));

  • #if 0

  • if((nbytes=read(sockfd,buffer_2,81))==-1)

  • {

  • fprintf(stderr,"Read Error:%s\n",strerror(errno));

  • exit(1);

  • }

  • ?
  • buffer_2[nbytes]='\0';

  • printf("Client received from Server %s\n",buffer_2);

  • #endif

  • ?
  • ?
  • }

  • close(sockfd);

  • exit(0);

  • }


  • ?

    ?

    創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

    總結(jié)

    以上是生活随笔為你收集整理的循环服务器,并发服务器模型以及I/O多路转接模型的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。