• <i id='s1hdn'><div id='s1hdn'><ins id='s1hdn'></ins></div></i>

  • <i id='s1hdn'></i>
    <dl id='s1hdn'></dl>
    1. <ins id='s1hdn'></ins>

      <code id='s1hdn'><strong id='s1hdn'></strong></code>
    2. <tr id='s1hdn'><strong id='s1hdn'></strong><small id='s1hdn'></small><button id='s1hdn'></button><li id='s1hdn'><noscript id='s1hdn'><big id='s1hdn'></big><dt id='s1hdn'></dt></noscript></li></tr><ol id='s1hdn'><table id='s1hdn'><blockquote id='s1hdn'><tbody id='s1hdn'></tbody></blockquote></table></ol><u id='s1hdn'></u><kbd id='s1hdn'><kbd id='s1hdn'></kbd></kbd>
      1. <fieldset id='s1hdn'></fieldset>
          <acronym id='s1hdn'><em id='s1hdn'></em><td id='s1hdn'><div id='s1hdn'></div></td></acronym><address id='s1hdn'><big id='s1hdn'><big id='s1hdn'></big><legend id='s1hdn'></legend></big></address>

          1. <span id='s1hdn'></span>

            Linux网络编程使用多进程实现服务器并发访问

            • 时间:
            • 浏览:11
            • 来源:124软件资讯网

                接纳多历程的方式实现服务器的并发会见的经范例例  。

                法式实现功效:

                1.客户端从尺度输入读入一行文字  ,发送到服务器.

                2.服务器吸收到客户端发来的文字后 ,原样返回给客户端.

                3.客户端吸收到服务器的发来的文字后  ,输出到尺度输出  ,然后继续以上步骤  。

                服务器端历程:建设好监听套接字后  ,等候客户端的毗连  ,吸收到一个毗连后  ,建立一个子历程来与客户端举行通讯 ,主历程则继续等候其他客户端的毗连  。代码如下:

                #include

                #include

                #include

                #include

                #include

                #include

                #include

                #include

                #include

                #define SERV_PORT 1113

                #define LISTENQ 32

                #define MAXLINE 1024

                

                void str_echo(int fd);

                int

                main(int argc, char *argv[]){

                int listenfd,connfd;

                pid_t childpid;

                socklen_t clilen;

                struct sockaddr_in servaddr;

                struct sockaddr_in cliaddr;

                if((listenfd = socket(AF_INET, SOCK_STREAM,0))==-1){

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

                exit(1);

                }

                

                bzero(&servaddr, sizeof(servaddr));

                servaddr.sin_family = AF_INET;

                servaddr.sin_addr.s_addr = htonl (INADDR_ANY);

                servaddr.sin_port = htons(SERV_PORT);

                

                if(bind(listenfd,(struct sockaddr*)(&servaddr),sizeof(struct sockaddr))==-1){

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

                exit(1);

                }

                

                if(listen(listenfd,5)==-1){

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

                exit(1);

                }

                for ( ; ; ) {

                clilen = sizeof(cliaddr);

                

                if((connfd=accept(listenfd,(struct sockaddr*)(&cliaddr),&clilen))==-1){

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

                exit(1);

                }

                //有客户端建设了毗连后

                if ( (childpid = fork()) == 0) {

                close(listenfd);

                str_echo(connfd);

                exit (0);

                }

                close(connfd);

                }

                }

                void str_echo(int sockfd){

                ssize_t n;

                char buf[MAXLINE];

                again:

                while ( (n = read(sockfd, buf, MAXLINE)) > 0)

                write(sockfd, buf, n);

                if (n < 0 && errno == EINTR)//被中止  ,重入

                goto again;

                else if (n < 0){//堕落

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

                exit(1);

                }

                }

                客户端历程:建立毗连套接字  ,自动向服务器提倡毗连请求  ,建设毗连后 ,等候尺度输入  ,输入完成后  ,将输入的内容发送给服务器  ,接着吸收服务器发送过来的内容  ,并将吸收到的内容输出到尺度输出  。代码如下:

                #include

                #include

                #include

                #include

                #include

                #include

                #include

                #include

                #include

                #define SERV_PORT 1113

                #define MAXLINE 1024

                void str_cli(FILE *fp, int sockfd);

                int

                main(int argc, char **argv)

                {

                int sockfd;

                struct sockaddr_in servaddr;

                if (argc != 2){

                fprintf(stderr,"usage: tcpcli \n\a");

                exit(0);

                }

                if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){

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

                exit(1);

                }

                

                bzero(&servaddr,sizeof(servaddr));

                servaddr.sin_family=AF_INET;

                servaddr.sin_port=htons(SERV_PORT);

                if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){

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

                exit(1);

                }

                

                if(connect(sockfd,(struct sockaddr *)(&servaddr),sizeof(struct sockaddr))==-1){

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

                exit(1);

                }

                str_cli(stdin, sockfd);

                exit(0);

                }

                void

                str_cli(FILE *fp, int sockfd)

                {

                int nbytes=0;

                char sendline[MAXLINE],recvline[MAXLINE];

                while (fgets(sendline, MAXLINE, fp) != NULL){//从尺度输入中读取一行

                write(sockfd, sendline, strlen(sendline));//将该行发送给服务器

                if ((nbytes=read(sockfd, recvline, MAXLINE)) == 0){//从sockfd读取从服务器发来的数据

                fprintf(stderr,"str_cli: server terminated prematurely\n");

                exit(1);

                }

                recvline[nbytes]='\0';

                fputs(recvline, stdout);

                }

                }

                运行效果:

                1.首先启动服务器端法式 。

                viidiot@ubuntu$ ./dissrv &(在后台运行)

                2.启动一个客户端

                viidiot@ubuntu$ ./discli 127.0.0.1

                hello  ,world!(客户端输入的内容)

                hello  ,world!(服务器端返回的内容)

                3.输入下令netstat -at检察tcp的毗连情形  ,可以发现服务器端与客户端已经建设起了一个毗连  ,而服务器的主历程则仍然在1113端口监听  ,等候毗连其他毗连的到来  。

                viidiot@ubuntu$ netstat –at

                tcp 0 0 *:1113 *:* LISTEN

                tcp 0 0 localhost.localdom:1113 localhost.localdo:57430 ESTABLISHED

                tcp 0 0 localhost.localdo:57430 localhost.localdom:1113 ESTABLISHED

                客户端输入EOF竣事通讯  。

                可是当我们开启多个客户端毗连到服务器举行通讯  ,完了之后通过按EOF竣事通讯后  ,可以从后台发现一个有趣的事情  ,即泛起了大量的僵尸历程  。如下所示:

                viidiot@ubuntu$ ps -a

                PID TTY TIME CMD

                19403 pts/1 00:00:00 dissrv

                19405 pts/1 00:00:00 dissrv

                19423 pts/1 00:00:00 dissrv

                19434 pts/1 00:00:00 dissrv

                19441 pts/1 00:00:00 dissrv

                造成大量僵尸历程的缘故原由是  ,服务器子历程终止时  ,会发送一个SIGCHLD信号给父历程 。但我们的代码中  ,并没有捕捉该信号  ,而这个信号的默认行动是忽略  ,因此  ,为了制止僵尸历程的发生  ,我们需要捕捉SIGCHLD来清晰僵尸历程 。