• 2017-2018 20155331 实验三实时系统


    2017-2018 20155331 实验三实时系统

    学习使用Linux命令wc(1)

    基于Linux Socket程序设计实现wc(1)服务器(端口号是你学号的后6位)和客户端

    客户端传一个文本文件给服务器

    服务器返加文本文件中的单词数

    实现截图:

    实验三-并发程序-2

    使用多线程实现wc服务器并使用同步互斥机制保证计数正确

    client.c

      #include <sys/types.h>
      #include <sys/socket.h>
      #include <netinet/in.h>
     #include <arpa/inet.h>
     #include <sys/time.h>
     #include <stdio.h>
    #include <errno.h>
    #include <string.h>
    #include <pthread.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #define PORT  8888
    #define BACKLOG 10
    #define MAXCONN 100
    #define BUFFSIZE 1024
    typedef unsigned char BYTE;
    typedef struct ClientInfo
    {
    struct sockaddr_in addr;
    int clientfd;
    int isConn;
    int index;
    } ClientInfo;
    	pthread_mutex_t activeConnMutex;
    	pthread_mutex_t clientsMutex[MAXCONN];
    	pthread_cond_t connDis;
    	pthread_t threadID[MAXCONN];
    	pthread_t serverManagerID;
    	ClientInfo clients[MAXCONN];
    	int serverExit = 0;
    	/*@brief Transform the all upper case 
    	*
    	*/
    	void tolowerString(char *s)
    	{
    int i=0;
    while(i < strlen(s))
    {
        s[i] = tolower(s[i]);
        ++i;
    } 
    }
    void listAll(char *all)
    {
    int i=0, len = 0;
    len += sprintf(all+len, "Index   		IP Address   		Port
    ");
    for(;i<MAXCONN;++i)
    {
        pthread_mutex_lock(&clientsMutex[i]);
        if(clients[i].isConn)
            len += sprintf(all+len, "%.8d		%s		%d
    ",clients[i].index, inet_ntoa(clients[i].addr.sin_addr), clients[i].addr.sin_port);
        pthread_mutex_unlock(&clientsMutex[i]);
    }
    }
    void clientManager(void* argv)
    {
    ClientInfo *client = (ClientInfo *)(argv);
    
    BYTE buff[BUFFSIZE];
    int recvbytes;
    
    int i=0;
    int clientfd = client->clientfd;
    struct sockaddr_in addr = client->addr;
    int isConn = client->isConn;
    int clientIndex = client->index;
    
    while((recvbytes = recv(clientfd, buff, BUFFSIZE, 0)) != -1)
    {
     //   buff[recvbytes] = '';
        tolowerString(buff);    //case-insensitive
        
        char cmd[100];
        if((sscanf(buff, "%s", cmd)) == -1)    //command error
        { 
           char err[100];         
           if(send(clientfd, err, strlen(err)+1, 0) == -1)
           {
               strcpy(err, "Error command and please enter again!
    ");
               fprintf(stdout, "%d sends an eroor command
    ", clientfd);
               break;
           }
        }
        else    
        {
            char msg[BUFFSIZE]; //The message content
            int dest = clientIndex; //message destination
            int isMsg = 0;              //any message needed to send
            if(strcmp(cmd, "disconn") == 0)
            {   
                pthread_cond_signal(&connDis);  //send a disconnetion signal and the waiting client can get response  
                break;
            }
            else if(strcmp(cmd, "time") == 0)
            {
                time_t now;
                struct tm *timenow;
                time(&now);
                timenow = localtime(&now);
                strcpy(msg, asctime(timenow));
                isMsg = 1;
            }
            else if(strcmp(cmd, "name") == 0)
            {
                strcpy(msg, "MACHINE NAME");
                isMsg = 1;
            }
            else if(strcmp(cmd, "list") == 0)
            {                            
                listAll(msg);
                isMsg = 1;
            }
            else if(strcmp(cmd, "send") == 0)
            {   
                    
                if(sscanf(buff+strlen(cmd)+1, "%d%s", &dest, msg)==-1 || dest >= MAXCONN)
                {
                    char err[100];
                    strcpy(err, "Destination ID error and please use list to check and enter again!
    ");
                    fprintf(stderr, "Close %d client eroor: %s(errno: %d)
    ", clientfd, strerror(errno), errno);
                    break;
                }
                fprintf(stdout, "%d %s
    ", dest, msg);   
                isMsg = 1;
            }
            else
            {
                char err[100];
                strcpy(err, "Unknown command and please enter again!
    ");
                fprintf(stderr, "Send to %d message eroor: %s(errno: %d)
    ", clientfd, strerror(errno), errno);
                break;
            }
            
            
            if(isMsg)
            {
                pthread_mutex_lock(&clientsMutex[dest]);
                if(clients[dest].isConn == 0)
                {
                    sprintf(msg, "The destination is disconneted!");
                    dest = clientIndex; 
                } 
                            
                if(send(clients[dest].clientfd, msg, strlen(msg)+1, 0) == -1)
                {
                    fprintf(stderr, "Send to %d message eroor: %s(errno: %d)
    ", clientfd, strerror(errno), errno);
                    pthread_mutex_unlock(&clientsMutex[dest]); 
                    break;
                }
                printf("send successfully!
    ");
                pthread_mutex_unlock(&clientsMutex[dest]); 
            }
        }  //end else       
    }   //end while
    
    pthread_mutex_lock(&clientsMutex[clientIndex]);
    client->isConn = 0;
    pthread_mutex_unlock(&clientsMutex[clientIndex]);
    
    if(close(clientfd) == -1)
        fprintf(stderr, "Close %d client eroor: %s(errno: %d)
    ", clientfd, strerror(errno), errno);
    fprintf(stderr, "Client %d connetion is closed
    ", clientfd);
    
    pthread_exit(NULL);
    }
    void serverManager(void* argv)
    {
    while(1)
    {
        char cmd[100];
        scanf("%s", cmd);
        tolowerString(cmd);
        if(strcmp(cmd, "exit") == 0)
            serverExit = 1;
        else if(strcmp(cmd, "list") == 0)
        {
            char buff[BUFFSIZE];
            listAll(buff);
            fprintf(stdout, "%s", buff);
        }
        else if(strcmp(cmd, "kill") == 0)
        {
            int clientIndex;
            scanf("%d", &clientIndex);
            if(clientIndex >= MAXCONN)
            {
                fprintf(stderr, "Unkown client!
    ");
                continue;
            }
            pthread_mutex_lock(&clientsMutex[clientIndex]);
            if(clients[clientIndex].isConn)
            {
                if(close(clients[clientIndex].clientfd) == -1)
                    fprintf(stderr, "Close %d client eroor: %s(errno: %d)
    ", clients[clientIndex].clientfd, strerror(errno), errno);
            }
            else
            {
                fprintf(stderr, "Unknown client!
    ");
            }
            pthread_mutex_unlock(&clientsMutex[clientIndex]);
            pthread_cancel(threadID[clientIndex]);
                
        }
        else
        {
            fprintf(stderr, "Unknown command!
    ");
        }
    }
    }
    int main()
    {
       int activeConn = 0;
       
       //initialize the mutex 
       pthread_mutex_init(&activeConnMutex, NULL);   
       pthread_cond_init(&connDis, NULL);
       int i=0;
       for(;i<MAXCONN;++i)
       pthread_mutex_init(&clientsMutex[i], NULL); 
    
       for(i=0;i<MAXCONN;++i)
           clients[i].isConn = 0; 
           
       //create the server manager thread
       pthread_create(&serverManagerID, NULL, (void *)(serverManager), NULL);
       
       
       int listenfd;
       struct sockaddr_in  servaddr;
        
       //create a socket
       if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
       {
       fprintf(stderr, "Create socket error: %s(errno: %d)
    ", strerror(errno), errno);
       exit(0);
       }
       else
           fprintf(stdout, "Create a socket successfully
    ");
       
       fcntl(listenfd, F_SETFL, O_NONBLOCK);       //set the socket non-block
       
       //set the server address
       memset(&servaddr, 0, sizeof(servaddr));  //initialize the server address 
       servaddr.sin_family = AF_INET;           //AF_INET means using TCP protocol
       servaddr.sin_addr.s_addr = htonl(INADDR_ANY);    //any in address(there may more than one network card in the server)
       servaddr.sin_port = htons(PORT);            //set the port
       
       //bind the server address with the socket
       if(bind(listenfd, (struct sockaddr*)(&servaddr), sizeof(servaddr)) == -1)
       {
        fprintf(stderr, "Bind socket error: %s(errno: %d)
    ", strerror(errno), errno);
        exit(0);
     }
    else
       fprintf(stdout, "Bind socket successfully
    ");
    
    //listen
     if(listen(listenfd, BACKLOG) == -1)
     {
       fprintf(stderr, "Listen socket error: %s(errno: %d)
    ", strerror(errno), errno);
       exit(0);
      }
       else
       fprintf(stdout, "Listen socket successfully
    ");
    
    
     while(1)
     {
       if(serverExit)
       {
           for(i=0;i<MAXCONN;++i)
           {
               if(clients[i].isConn)
               {
                   if(close(clients[i].clientfd) == -1)         //close the client 
                       fprintf(stderr, "Close %d client eroor: %s(errno: %d)
    ", clients[i].clientfd, strerror(errno), errno);
                   if(pthread_cancel(threadID[i]) != 0)         //cancel the corresponding client thread
                        fprintf(stderr, "Cancel %d thread eroor: %s(errno: %d)
    ", (int)(threadID[i]), strerror(errno), errno);
               }
           }
           return 0;    //main exit;
       }
       
       pthread_mutex_lock(&activeConnMutex);
       if(activeConn >= MAXCONN)
            pthread_cond_wait(&connDis, &activeConnMutex);
       pthread_mutex_unlock(&activeConnMutex);
           
       //find an empty postion for a new connnetion
       int i=0;
       while(i<MAXCONN)
       {
           pthread_mutex_lock(&clientsMutex[i]);
           if(!clients[i].isConn)
           {
               pthread_mutex_unlock(&clientsMutex[i]);
               break;
           }
           pthread_mutex_unlock(&clientsMutex[i]);
           ++i;           
       }   
       
       //accept
       struct sockaddr_in addr;
       int clientfd;
       int sin_size = sizeof(struct sockaddr_in);
       if((clientfd = accept(listenfd, (struct sockaddr*)(&addr), &sin_size)) == -1)
       {   
           sleep(1);        
           //fprintf(stderr, "Accept socket error: %s(errno: %d)
    ", strerror(errno), errno);
           continue;
           //exit(0);
       }
       else
           fprintf(stdout, "Accept socket successfully
    ");
       
       pthread_mutex_lock(&clientsMutex[i]);
       clients[i].clientfd = clientfd;
       clients[i].addr = addr;
       clients[i].isConn = 1;
       clients[i].index = i;
       pthread_mutex_unlock(&clientsMutex[i]);
       
       //create a thread for a client
       pthread_create(&threadID[i], NULL, (void *)clientManager, &clients[i]);     
       
      }    //end-while
    }
    

    server.c

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <stdio.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <errno.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #include <pthread.h>
    #define BUFFERSIZE 1024
    typedef unsigned char BYTE;
    pthread_t receiveID;
    void tolowerString(char *s)
    {
    int i=0;
    while(i < strlen(s))
    {
        s[i] = tolower(s[i]);
        ++i;
    } 
    }
     receive(void *argv)
    {
    int sockclient = *(int*)(argv);
    BYTE recvbuff[BUFFERSIZE];
    while(recv(sockclient, recvbuff, sizeof(recvbuff), 0)!=-1) //receive
    {
        fputs(recvbuff, stdout);
        fputs("
    ", stdout);      
    }
    fprintf(stderr, "Receive eroor: %s(errno: %d)
    ", strerror(errno), errno);
    }
    int main()
    {
    ///define sockfd
    int sockclient = socket(AF_INET,SOCK_STREAM, 0);
    ///definet sockaddr_in
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    
    int isConn = 0;
    
    BYTE buff[BUFFERSIZE];
    
    while (fgets(buff, sizeof(buff), stdin) != NULL)
    {
        tolowerString(buff);
        char cmd[100], ip[100];
        int port;
        if(sscanf(buff, "%s", cmd) == -1)    //command error
        { 
            fprintf(stderr, "Input eroor: %s(errno: %d) And please input again
    ", strerror(errno), errno);
            continue;
        }
        if(strcmp(cmd, "conn") == 0)        //connecton command
        {
            char ip[100];
            int port, ipLen=0;
            if(sscanf(buff+strlen(cmd)+1, "%s", ip) == -1)    //command error
            { 
                fprintf(stderr, "Input eroor: %s(errno: %d) And please input again
    ", strerror(errno), errno);
                continue;
            }
            if((sscanf(buff+strlen(cmd)+strlen(ip)+2, "%d", &port)) == -1)    //command error
            { 
                fprintf(stderr, "Input eroor: %s(errno: %d) And please input again
    ", strerror(errno), errno);
                continue;
            }  
           // fprintf(stdout, "%s %d
    ",ip, port);          
            servaddr.sin_family = AF_INET;
            servaddr.sin_port = htons(port);  ///server port
            servaddr.sin_addr.s_addr = inet_addr(ip);  //server ip
            if (connect(sockclient, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
            {
                fprintf(stderr, "Connect eroor: %s(errno: %d)
    ", strerror(errno), errno);
                continue;
            } 
            fprintf(stdout, "Connect successfully
    "); 
            isConn = 1;  
            pthread_create(&receiveID, NULL, (void *)(receive), (void *)(&sockclient));            
        }
        else if(strcmp(cmd, "disconn") == 0)
        {
            if(isConn == 0)
            {
                fprintf(stdout, "There is not a connection!
    ");
                continue;
            }
            else
            {
                pthread_cancel(receiveID);
                close(sockclient);
            }   
            isConn = 0;
        }
        else if(strcmp(cmd, "quit") == 0)
        {
            if(isConn)
            {
                pthread_cancel(receiveID);
                close(sockclient);
            }
            return 0;
        }
        else
        {
            if(send(sockclient, buff, strlen(buff)+1, 0) == -1) //send
            {
                fprintf(stderr, "Send eroor: %s(errno: %d)
    ", strerror(errno), errno);
                continue;
            }
            
            if(isConn == 0)
            {
                fprintf(stdout, "Please use conn <ip> <port> command to build a connnection!
    ");
                continue;
            }
            memset(buff, 0, sizeof(buff));
        }      
    }
    close(sockclient);
    return 0;
    }
  • 相关阅读:
    is quoted with ["] which must be escaped when used within the value
    QueryDSL与SpringDataJPA复杂查询
    遍历list,同时remove不符合条件的元素
    解决AnnotationTransactionAttributeSource is only available on Java 1.5 and highe
    Windows系统安装MySQL
    sqlyog导sql文件
    myeclipse导入maven项目
    Invalid 'log4jConfigLocation' parameter: class path resource [log4j.xml] cannot be resolved to URL because it does not exist
    Nginx SSL+tomcat集群,取不到https正确协议
    微信开发之通过代理调试本地项目
  • 原文地址:https://www.cnblogs.com/dd1174751354/p/7865489.html
Copyright © 2020-2023  润新知