• 并发服务器


    多进程并发服务器

    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    #include<arpa/inet.h>
    #include<ctype.h>
    #include<strings.h>
    #include<sys/wait.h>
    #include"wrap.h"
    #define SERV_PORT 8888
    #define SERV_IP "192.227.231.111"
    
    void wait_child(int sign)
    {
    	while(waitpid(0,NULL,WNOHANG)>0);
    	return ;
    }
    int main()
    {
    	pid_t pid;
    	int lfd,cfd;
    	lfd=Socket(AF_INET,SOCK_STREAM,0);

        int opt = 1;
         setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //设置端口复用
    	struct sockaddr_in serv_addr,clie_addr;
    	socklen_t clie_addr_len;
    	clie_addr_len=sizeof(clie_addr);
    	
    	bzero(&serv_addr,sizeof(serv_addr));
    	serv_addr.sin_family=AF_INET;
    	serv_addr.sin_port=htons(SERV_PORT);
    	
    	//serv_addr.sin_addr.s_addr=htonol(INADDR_ANY); 使用可用的ip
    	//指定ip  用inet_pton转换
    	inet_pton(AF_INET,SERV_IP,&serv_addr.sin_addr.s_addr);
    	Bind(lfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
    	
    	Listen(lfd,128);
    	
    	char buf[BUFSIZ],buf_ip[BUFSIZ];
    	int n,i;
    	while(1)
    	{
    		cfd=Accept(lfd,(struct sockaddr*)&clie_addr,&clie_addr_len);
    	
    		printf("client:%s port:%d has connected",inet_ntop(AF_INET,&clie_addr.sin_addr.s_addr,buf_ip,sizeof(buf_ip)),ntohs(clie_addr.sin_port));
    		pid=fork();
    		if(pid<0)
    		{
    				perror("fork err");
    				exit(1);
    		}else if(pid==0)
    		{
    			close(lfd);
    			break;
    	
    		}else{
    			close(cfd);	
    			signal(SIGCHLD,wait_child);
    			
    		}
    	}
    	if(pid==0)
    	{
    		while(1)
    		{
    			n=Read(cfd,buf,sizeof(buf));
    			if(n==0)
    			{
    				close(cfd);
    				return 0;//client close
    			}else if(n==-1)
    			{
    				perror("read err");
    				exit(1);
    			}else{
    				for(i=0;i<n;i++)
    				{
    					buf[i]=toupper(buf[i]);
    				}
    			}
    			
    			write(cfd,buf,n);
    		}
    	}
    		
    }
    

     

    多线程并发服务器

    #include <stdio.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <pthread.h>
    #include <ctype.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    #include "wrap.h"
    
    #define MAXLINE 8192
    #define SERV_PORT 8000
    
    struct s_info {                     //定义一个结构体, 将地址结构跟cfd捆绑
        struct sockaddr_in cliaddr;
        int connfd;
    };
    
    void *do_work(void *arg)
    {
        int n,i;
        struct s_info *ts = (struct s_info*)arg;
        char buf[MAXLINE];
        char str[INET_ADDRSTRLEN];      //#define INET_ADDRSTRLEN 16  可用"[+d"查看
    
        while (1) {
            n = Read(ts->connfd, buf, MAXLINE);                     //读客户端
            if (n == 0) {
                printf("the client %d closed...
    ", ts->connfd);
                break;                                              //跳出循环,关闭cfd
            }
            printf("received from %s at PORT %d
    ",
                    inet_ntop(AF_INET, &(*ts).cliaddr.sin_addr, str, sizeof(str)),
                    ntohs((*ts).cliaddr.sin_port));                 //打印客户端信息(IP/PORT)
    
            for (i = 0; i < n; i++) 
                buf[i] = toupper(buf[i]);                           //小写-->大写
    
            Write(STDOUT_FILENO, buf, n);                           //写出至屏幕
            Write(ts->connfd, buf, n);                              //回写给客户端
        }
        Close(ts->connfd);
    
        return (void *)0;
    }
    
    int main(void)
    {
        struct sockaddr_in servaddr, cliaddr;
        socklen_t cliaddr_len;
        int listenfd, connfd;
        pthread_t tid;
        struct s_info ts[256];      //根据最大线程数创建结构体数组.
        int i = 0;
    
        listenfd = Socket(AF_INET, SOCK_STREAM, 0);                     //创建一个socket, 得到lfd
    
        bzero(&servaddr, sizeof(servaddr));                             //地址结构清零
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);                   //指定本地任意IP
        servaddr.sin_port = htons(SERV_PORT);                           //指定端口号 8000
    
        Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); //绑定
    
        Listen(listenfd, 128);      //设置同一时刻链接服务器上限数
    
        printf("Accepting client connect ...
    ");
    
        while (1) {
            cliaddr_len = sizeof(cliaddr);
            connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);   //阻塞监听客户端链接请求
            ts[i].cliaddr = cliaddr;
            ts[i].connfd = connfd;
    
            /* 达到线程最大数时,pthread_create出错处理, 增加服务器稳定性 */
            pthread_create(&tid, NULL, do_work, (void*)&ts[i]);
            pthread_detach(tid);                                                    //子线程分离,防止僵线程产生.
            i++;
        }
    
        return 0;
    }
    

      

     

  • 相关阅读:
    Vue.js 学习报告
    Javascript 巩固:阮一峰javascript教程 (2017-1-17)
    2017-1-17
    my-Life项目开发流程-02
    《Javascript 权威指南 第六版》
    2017-1-11
    2017-1-10
    2017-1-9
    前端知识解惑: 响应式 兼容性 不错的知识链接
    2017-1-3
  • 原文地址:https://www.cnblogs.com/sclu/p/11295591.html
Copyright © 2020-2023  润新知