linux_echo_用户态服务器

来源:互联网 发布:windows curl命令详解 编辑:程序博客网 时间:2024/06/16 17:50

server.h

/* * Copyright(C) 2016 Ruijie Network. All rights reserved. *//* * server.h * Original Author: suntianyu@ruijie.com.cn,  2016-8-7 * * echo User server * * History * */  #ifndef SERVER_H#define SERVER_H#include <pthread.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/un.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <signal.h>#include <fcntl.h>#include <errno.h>#define ERROR              -1           #define MAX_USERS           2 #define DATA_LEN            30 #define NETLINK_ECHO        31#define KTHREAD_NUM         4#define NORMAL_LEN          512#define MAX_USERS           2#define ERROR               -1#define NORMAL_MODE         3#define UPPER_MODE          2#define LOWER_MODE          1#define NATIVE              0#define PIDTB_SIZE          2#define TABLE_SIZE          3#define ECHOTB_SIZE         4#define TEN                 10#define READ_NOW            1#define TOASCI              32#define MODE_SIZE           4#define UPPER_SIZE          5#define LOWER_SIZE          5#define NORMAL_SIZE         6/* judge */int judge_input(char *input_buf);/* file lock */int signal_instance(void);/* cmd function */void  *cmd_handle(void* arg);/* quit */void  quit(void);/* cmd thread */void  cmd_running(void);/* socket thread function */void  *msg_handle(void* arg);/* socket thread */void  server_running(void);/* itoa */void  my_itoa(int n,char *s);/* pid_table */void  init_pid_table(int native_mode);/* quit */void  quit_all(void);/* quit */void  disconect(int pid);/* pid_table */void  insert_pid(int pid);/* pid_table */void  delete_pid(int pid);/* pid_table */int   find_outmode(int pid);/* pid_table */int   set_outmode(int pid,int mode);#endif

server.c

/* * Copyright(C) 2016 Ruijie Network. All rights reserved. *//* * server.c * Original Author: suntianyu@ruijie.com.cn,  2016-8-7 * * echo User server * * History * */  #include "server.h"pthread_t tid;                   pthread_attr_t attr;                     pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;int native_mode = NORMAL_MODE;int characters = NATIVE, clients = NATIVE;int output_config[TABLE_SIZE] = {NATIVE,NATIVE,NORMAL_MODE};int pid_outmode[PIDTB_SIZE][MAX_USERS];int sk_server;              int sk_client;               char echo_database[ECHOTB_SIZE][DATA_LEN] = {"Server info:","   Global mode: normal   ","   characters:  0    ","   clients:  0    "};                    struct sockaddr_un srv_address;struct sockaddr_un usr_address;int main(void){    if ( signal_instance() == ERROR ) {        return ERROR;    }    init_pid_table(native_mode);    signal(SIGPIPE,SIG_IGN);    cmd_running();    server_running();     return 0;}/* thread function */void* msg_handle(void* arg){    int num, i,*p_id;    int client_sock;    char tmp[5] = " ";    char buf[100] = {" "};    if(arg == NULL) {        return NULL;    }    p_id = (int *) arg;    client_sock = *p_id;    free(arg);    pthread_mutex_lock(&mutex);    if (clients > MAX_USERS) {        printf("警告!用户数目已达上限!!!\n");        clients--;        pthread_mutex_unlock(&mutex);        return;    }    pthread_mutex_unlock(&mutex);    if (client_sock > 9) {        my_itoa(client_sock,tmp);    } else {        tmp[0]='0' + client_sock;    }    send(client_sock,tmp,5,0);      while (1) {        memset(buf,0,sizeof(buf));        num = recv(client_sock,buf,100,0);        pthread_mutex_lock(&mutex);        if (num == 0) {            disconect(client_sock);            pthread_mutex_unlock(&mutex);                 return;        } else {            characters++;            pthread_mutex_unlock(&mutex);        }                if (find_outmode(client_sock) == 1) {            for (i = 0; ((i < strlen(buf)) && (buf[i] != '\0')); i++ ) {                if ( buf[i] >= 'A' && buf[i] <= 'Z') {                    buf[i] = buf[i] + TOASCI;                }            }        }   else if (find_outmode(client_sock) == 2) {            for (i = 0; ((i < strlen(buf)) && (buf[i] != '\0')); i++ ) {                if ( buf[i] >= 'a' && buf[i] <= 'z') {                    buf[i] = buf[i] - TOASCI;                }            }        }        usleep(strlen(buf)*200000);        num = send(client_sock,buf,num,0);          if (num == 0) {            pthread_mutex_lock(&mutex);            disconect(client_sock);            pthread_mutex_unlock(&mutex);            return;        }        } }/* input cmd function */void* cmd_handle(void* arg){    /* show mode quit */    char cmd[30] = {"\0"};    int i,j;    while (1) {        printf("SERVER>  ");        fgets(cmd, 30, stdin);        judge_input(cmd);        if (output_config[0] == 1) {            pthread_mutex_lock(&mutex);            output_config[0] = 0;            if (output_config[1] == 0) {                native_mode = output_config[2];                for (i=0; i < MAX_USERS; i++) {                    pid_outmode[1][i] = native_mode;                }            }   else {                set_outmode(output_config[1],output_config[2]);            }            pthread_mutex_unlock(&mutex);        }    }  }/* file lock */int signal_instance(void){    int ret;    struct flock file_lk;    unlink("/tmp/echo_address");    file_lk.l_start = 0;    file_lk.l_type = F_WRLCK;    file_lk.l_len = 0;    file_lk.l_whence = SEEK_SET;    if ((ret = open("server_lock",O_WRONLY | O_CREAT,0666)) < 0) {        return ERROR;    }    if (fcntl(ret,F_SETLK,&file_lk) < 0) {        if (errno == EACCES || errno == EAGAIN) {            printf("Other instance is running\n");            exit(-1);        } else {            return ERROR;        }    }}/* thread cmd function */void cmd_running(void){    int ret;    pthread_attr_init(&attr);    pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);    ret = pthread_create(&tid,&attr,cmd_handle,NULL);    if (ret != 0) {        printf("pthread cmd created fail!\n");        exit(-1);        } }/* thread socket function */void server_running(void){    int ret,*p;    socklen_t len;    len = sizeof(usr_address);    sk_server = socket(AF_UNIX,SOCK_STREAM,0);    if (sk_server == -1) {        printf("socket() error\n");        return;    }    srv_address.sun_family = AF_UNIX;    strcpy(srv_address.sun_path,"/tmp/echo_address");    ret = bind(sk_server,(struct sockaddr *)&srv_address,sizeof(srv_address));    if (ret == -1) {        printf("bind() error\n");            return;    }    listen(sk_server,10);    while (1) {        sk_client = accept(sk_server,(struct sockaddr*)&usr_address,&len);        if (sk_client == -1) {            printf("accept() fail\n");             return;            }         p = (int *)malloc(sizeof(int));        if (p == NULL) {            return;        }        *p = sk_client;        insert_pid(sk_client);        printf("Client id=%d connected!\n", sk_client);        if (sk_client > 0) {            ret = pthread_create(&tid,&attr,msg_handle,(void *)p);              if (ret != 0) {                printf("pthread created fail!\n");                return ;                }                  }                                           sleep(1);    } }/*  atoi  */int my_atoi(char *str){    int i,value;    value = 0;    if (str == NULL) {        return;    }    for (i = 0; i < DATA_LEN; i++){            if (*str >= '0' && *str <= '9'){            value *= TEN;            value += *str - '0';        }        str++;    }    return value;}/* itoa */void my_itoa(int n,char *s){    int sign,i;    char *p;    char *q;    char temp;    if (s == NULL) {        return;    }    i = 0;    sign = n;    p = s;    q = s;    if (sign < 0) {        n = -n;    }        do {        s[i++] = n % TEN + '0';        n = n / TEN;    }   while (n > 0);    if (sign < 0) {        s[i++] = '-';    }    s[i] = '\0';    /* rev */    while ('\0' != *(++q + 1)) {    }    while (p < q) {        if (*p != *q) {            temp = *p;            *p = *q;            *q = temp;        }        ++p;        --q;    }}/****************************/    /*      input judge     */  /****************************/  int judge_input(char *input_buf){    int i,j;       char show[MODE_SIZE] = "show";    char quit[MODE_SIZE] = "quit";    char mode[MODE_SIZE] = "mode";    char char_lower[LOWER_SIZE] = "lower";    char char_upper[UPPER_SIZE] = "upper" ;    char char_normal[6] = "normal";    if (input_buf == NULL) {        return 0;    }    /* show */    for (i = 0; i < MODE_SIZE; i++) {        if ((*(input_buf + i)) != show[i]) {            break;        }    }    if (i == MODE_SIZE && strlen(input_buf) == 5) {        if (characters < 10) {            echo_database[2][15] = '0' + characters;            echo_database[2][16] = ' ';        }   else {            my_itoa(characters,&echo_database[2][15]);            }        if (clients < 10) {            echo_database[3][12] = '0' + clients;            echo_database[3][13] = ' ';        }   else {            my_itoa(clients,&echo_database[3][12]);        }        printf("%s\n", echo_database[0]);        printf("%s\n", echo_database[1]);        printf("%s\n", echo_database[2]);        printf("%s\n", echo_database[3]);        return 0;    }    /* quit */    for (i = 0; i < MODE_SIZE; i++) {        if ((*(input_buf + i)) != quit[i]) {            break;        }    }    if (i == MODE_SIZE && strlen(input_buf) == 5) {        printf("EXIT SERVER !!!\n");        quit_all();        return 0;    }    /* mode */    for (i = 0; i < MODE_SIZE; i++) {        if ((*(input_buf + i)) != mode[i]){            printf("Please input 'show'  'quit' or 'mode ... ...'\n");            return ERROR;        }    }    /* pid */    output_config[1] = my_atoi(input_buf);    /* lower */    for (i = MODE_SIZE,j=0; i < DATA_LEN; i++) {        if ( (*(input_buf + i) >= 'a' &&*(input_buf + i) <= 'z') || (*(input_buf + i) >= 'A' &&*(input_buf + i) <= 'Z') ){            if ((*(input_buf + i)) != char_lower[j]) {                break;            }   else {                          j++;            }                         }        if (j == LOWER_SIZE) {            output_config[0] = 1;                           output_config[2] = 1;            if (output_config[1] == 0) {                memcpy(&echo_database[1][16],char_lower,LOWER_SIZE);                echo_database[1][21] = '\0';            }            return 1;        }    }    /* upper */    for (i = MODE_SIZE,j=0; i < DATA_LEN; i++){        if ( (*(input_buf + i) >= 'a'&&*(input_buf + i) <= 'z') || (*(input_buf + i) >= 'A'&&*(input_buf + i) <= 'Z') ){            if ((*(input_buf + i)) != char_upper[j]) {                break;            }   else {                j++;            }        }        if (j == UPPER_SIZE) {            output_config[0] = 1;             output_config[2] = 2;            if (output_config[1] == 0) {                memcpy(&echo_database[1][16],char_upper,UPPER_SIZE);                     echo_database[1][21] = '\0';            }            return 1;        }    }    /* normal */    for (i = MODE_SIZE,j=0; i < DATA_LEN; i++) {        if ( (*(input_buf + i) >= 'a'&& *(input_buf + i) <= 'z') || (*(input_buf + i) >= 'A' &&*(input_buf + i) <= 'Z') ) {            if ((*(input_buf + i)) != char_normal[j]) {                break;            }   else {                 j++;            }        }        if (j == 6) {            output_config[0] = 1;             output_config[2] = 3;            if (output_config[1] == 0) {                memcpy(&echo_database[1][16],char_normal,6);            }            return 1;        }    }    return 0;}/****************************/  /*       pid  table         */  /****************************/  void init_pid_table(int native_mode){    int i;    for (i=0; i < MAX_USERS; i++) {        pid_outmode[0][i] = 0;       }      for (i=0; i < MAX_USERS; i++) {        pid_outmode[1][i] = native_mode;    }          }/* pid table */void insert_pid(int pid){    int i;    clients++;    for (i=0; i < MAX_USERS; i++) {        if (pid_outmode[0][i] == pid) {            return;        }    }    for (i=0; i < MAX_USERS; i++) {        if (pid_outmode[0][i] == 0) {            pid_outmode[0][i] = pid;             pid_outmode[1][i] = native_mode;                            return;        }    }    return;}/* pid table */void delete_pid(int pid){    int i;    for (i=0; i < MAX_USERS; i++) {        if (pid_outmode[0][i] == pid){            clients--;            pid_outmode[1][i] = native_mode;            pid_outmode[0][i] = 0;            return;        }    }    return;}/* pid table */int find_outmode(int pid){    int i;    for (i=0; i < MAX_USERS; i++) {        if (pid_outmode[0][i] == pid){                    return pid_outmode[1][i];        }    }    return native_mode;}/* pid table */int set_outmode(int pid,int mode){    int i;    for (i=0; i < MAX_USERS; i++) {        if (pid_outmode[0][i] == pid){                    pid_outmode[1][i] = mode;        }    }    return 0;}  /* pid table */void quit_all(void){     pthread_mutex_destroy(&mutex);    exit(0);}/* pid table */void disconect(int pid){                             delete_pid(pid);    return;}


0 0
原创粉丝点击