/date 航班信息文件
/register 用户注册信息文件
/user 用户购票信息文件
server
#include "head.h" char chars[10]; char sendbuf[1024]; struct list_node{ char name[10];//用户名 char passwd[10];//密码 char number[10];//航班号 char staddress[10];//起点站 char arraddress[10];//终点站 char date[10];//班期 char type[10];//机型 char stime[10];//起飞时间 char price[10];//票价 char aggregate[10];//总金额 struct list_head list;//内核链表指针域 }; struct list_node_ip{ int connfd; char ip[50]; pthread_t tid; struct list_head list; }; struct list_node_ip *head = NULL; //初始化内核链表头 struct list_node_ip *init_list_head_ip(struct list_node_ip *head) { head = (struct list_node_ip *)malloc(sizeof(struct list_node_ip)); if(head ==NULL) printf("malloc head error! "); INIT_LIST_HEAD(&(head->list)); return head; } //尾插数据 int add_list_node_ip(struct list_node_ip *head,int sockfd,char ip[50],pthread_t tid) { struct list_node_ip *Node = NULL; Node = (struct list_node_ip *)malloc(sizeof(struct list_node_ip)); if(Node == NULL) printf("malloc Node error "); Node->connfd = sockfd; strcpy(Node->ip,ip); Node->tid = tid; list_add_tail(&(Node->list),&(head->list)); return 0; } //线程退出删除对应链表 int delete_list_node_num_ip(struct list_node_ip *head,pthread_t tid) { struct list_node_ip *p = NULL; struct list_node_ip *q = NULL; list_for_each_entry_safe(p,q,&(head->list),list) { if(p->tid == tid) { list_del(&(p->list)); free(p); } } return 0; } //根据提供的connfd查找线程是否存在,存在返回1,不存在返回0 int find_list_node_num(struct list_node_ip *head,int connfd) { struct list_node_ip *p = NULL; struct list_node_ip *q = NULL; list_for_each_entry_safe(p,q,&(head->list),list) { if(p->connfd == connfd) { return p->connfd ; } } return 0; } //删除整条链表 int delete_list_ip(struct list_node_ip *head) { struct list_node_ip *p = NULL; struct list_node_ip *q = NULL; list_for_each_entry_safe(p,q,&(head->list),list) { list_del(&(p->list)); free(p); } list_del(&(head->list)); free(head); return 0; } /*获取数字字符*/ int char_input(int connfd) { bzero(chars,sizeof(chars)); fd_set rset; char buf[10]; char *str; int get; int maxfd = connfd > STDIN_FILENO ? connfd : STDIN_FILENO; while(1) { FD_ZERO(&rset); FD_SET(connfd,&rset); FD_SET(STDIN_FILENO,&rset); select(maxfd+1,&rset,NULL,NULL,NULL); if(FD_ISSET(STDIN_FILENO,&rset)) { bzero(chars,sizeof(chars)); fgets(chars,sizeof(chars),stdin); return 1; } if(connfd != 0) { bzero(buf,sizeof(buf)); if(recv(connfd,buf,sizeof(buf),0)>0) str = strtok(buf, " "); strcpy(chars,str); printf("%s ",chars); return 1; } } return ; } /*申请链表头,返回链表头*/ struct list_node *init_list_head(struct list_node *_head,int connfd) { _head = (struct list_node *)malloc(sizeof(struct list_node)); if(_head == NULL) { printf("malloc head error! "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"malloc head error! "); send(connfd,sendbuf,strlen(sendbuf),0); } INIT_LIST_HEAD(&(_head->list)); return _head; } /*管理员用户新增航班*/ int tail_add_list_plant(struct list_node *p_head,int connfd) { char buff[50] = {0}; char name[10],passwd[10]; struct list_node *Node = NULL; Node = (struct list_node *)malloc(sizeof(struct list_node)); if(Node == NULL) { printf("malloc Node error! "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"malloc Node error! "); send(connfd,sendbuf,strlen(sendbuf),0); } printf("please input your name: "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"please input your name: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(name,chars); break; } printf("passwd:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"passwd: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(passwd,chars); break; } if(strcmp(name,"admin") == 0 && strcmp(passwd,"admin123") == 0)//管理员用户才可以修改航班信息,账户为admin,密码为admin123 { strcpy(Node->name,name); strcpy(Node->passwd,passwd); printf("number:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"number: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(Node->number,chars); break; } //1. 打开目录 DIR *dp = opendir("./date"); if(dp == NULL) { printf("opendir error! "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"opendir error! "); send(connfd,sendbuf,strlen(sendbuf),0); } //2. 切换到目录下 chdir("./date"); sprintf(buff,"%s.txt",Node->number); FILE *fp = fopen(buff,"a"); bzero(buff,sizeof(buff)); printf("staddress:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"staddress: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(Node->staddress,chars); break; } printf("arraddress:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"arraddress: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(Node->arraddress,chars); break; } printf("date:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"date: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(Node->date,chars); break; } printf("type:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"type: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(Node->type,chars); break; } printf("stime:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"stime: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(Node->stime,chars); break; } printf("price:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"price: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(Node->price,chars); break; } sprintf(buff,"%s,%s,%s,%s,%s,%s,%s",Node->number,Node->staddress,Node->arraddress,Node->date,Node->type,Node->stime,Node->price); fwrite(buff,50,1,fp); list_add_tail(&(Node->list),&(p_head->list)); fclose(fp); chdir("../"); closedir(dp); return 0; } else printf("You're not the administrator "); return 1; } /*管理员删除航班*/ int delete_list_node_number(struct list_node *p_head,int connfd) { char buff[50] = {0}; char buf[50] = {0}; char name[10],passwd[10],number[10]; struct list_node *p = NULL; struct list_node *q = NULL; printf("please input your name: "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"please input your name: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(name,chars); break; } printf("passwd:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"passwd: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(passwd,chars); break; } if(strcmp(name,"admin") == 0 && strcmp(passwd,"admin123") == 0)//管理员用户才可以修改航班信息,账户为admin,密码为admin123 { printf("number:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"number: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(number,chars); break; } list_for_each_entry_safe(p,q,&(p_head->list),list) { if(strcmp(p->number,number) == 0) { DIR *dp = opendir("./date"); if(dp == NULL) { bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"opendir error! "); send(connfd,sendbuf,strlen(sendbuf),0); printf("opendir error! "); } //2. 切换到目录下 chdir("./date"); sprintf(buff,"rm %s.txt",number); system(buff); list_del(&(p->list)); free(p); printf("%s remove ",number); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"%s remove! ",number); send(connfd,sendbuf,strlen(sendbuf),0); chdir("../"); closedir(dp); return 0; } } } else printf("You don't have access "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"You don't have access "); send(connfd,sendbuf,strlen(sendbuf),0); return -1; } /*普通用户注册*/ int tail_add_list_user(struct list_node *u_head,int connfd) { struct list_node *Node = NULL; char buff[100]; Node = (struct list_node *)malloc(sizeof(struct list_node)); if(Node == NULL) { bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"malloc Node error! "); send(connfd,sendbuf,strlen(sendbuf),0); printf("malloc Node error! "); } printf("please input your name: "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"please input your name: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(Node->name,chars); break; } printf("passwd:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"passwd: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(Node->passwd,chars); break; } DIR *dp = opendir("./register"); if(dp == NULL) { bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"opendir error! "); send(connfd,sendbuf,strlen(sendbuf),0); printf("opendir error! "); } chdir("./register"); sprintf(buff,"%s.txt",Node->name); FILE *fp = fopen(buff,"a"); bzero(buff,sizeof(buff)); sprintf(buff,"%s,%s",Node->name,Node->passwd); fwrite(buff,50,1,fp); fclose(fp); chdir("../"); closedir(dp); list_add_tail(&(Node->list),&(u_head->list)); printf("Registration Successful "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"Registration Successful "); send(connfd,sendbuf,strlen(sendbuf),0); return 0; } /*普通用户登入购买票系统,返回注册后用户的地址*/ struct list_node *user_name_show_list(struct list_node *u_head,int connfd) { struct list_head *p = NULL; struct list_node *tmp = NULL; char name[10],passwd[10]; printf("please input your name: "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"please input your name: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(name,chars); break; } printf("passwd:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"passwd: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(passwd,chars); break; } list_for_each_prev(p,&(u_head->list)) { tmp = list_entry(p,struct list_node,list); if(strcmp(name,tmp->name) == 0 && strcmp(passwd,tmp->passwd) == 0) return tmp; } printf("you do namet register "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"you do namet register "); send(connfd,sendbuf,strlen(sendbuf),0); return NULL; } /*普通用户购票,输入登陆用户的地址和航班的头*/ int user_buy_fun(struct list_node *u_head,struct list_node *p_head,int connfd) { int a,b,c; char number[10],buf[10]; struct list_head *p = NULL; struct list_node *tmp = NULL; printf("pleasse input number: "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"pleasse input number: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(number,chars); break; } list_for_each_prev(p,&(p_head->list))//查看用户是否购买过此航班 { tmp = list_entry(p,struct list_node,list); if(strcmp(tmp->number,u_head->number) == 0) { printf("you have %s fight ",tmp->number); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"you have %s fight ",tmp->number); send(connfd,sendbuf,strlen(sendbuf),0); } } list_for_each_prev(p,&(p_head->list))//未购买则执行买票程序 { tmp = list_entry(p,struct list_node,list); if(strcmp(tmp->number,number) == 0) { if(u_head->price == 0)//判断是否是第一张机票 { printf("%s ",u_head->name); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"%s ",u_head->name); send(connfd,sendbuf,strlen(sendbuf),0); strcpy(u_head->number,tmp->number); strcpy(u_head->staddress,tmp->staddress); strcpy(u_head->arraddress,tmp->arraddress); strcpy(u_head->date,tmp->date); strcpy(u_head->type,tmp->type); strcpy(u_head->stime,tmp->stime); strcpy(u_head->price,tmp->price); strcpy(u_head->price,tmp->price); strcpy(u_head->aggregate,u_head->price); printf("you need pay for %s rmb",u_head->aggregate); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"you need pay for %s rmb",u_head->aggregate); send(connfd,sendbuf,strlen(sendbuf),0); } else//如果不是第一张机票则在链表后加一节点 { struct list_node *Node = NULL; Node = (struct list_node *)malloc(sizeof(struct list_node)); if(Node == NULL) { bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"malloc Node error! "); send(connfd,sendbuf,strlen(sendbuf),0); printf("malloc Node error! "); } printf("%s ",u_head->name); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"%s ",u_head->name); send(connfd,sendbuf,strlen(sendbuf),0); strcpy(Node->name,u_head->name); strcpy(Node->passwd,u_head->passwd); strcpy(Node->number,tmp->number); strcpy(Node->staddress,tmp->staddress); strcpy(Node->arraddress,tmp->arraddress); strcpy(Node->date,tmp->date); strcpy(Node->type,tmp->type); strcpy(Node->stime,tmp->stime); strcpy(Node->price,tmp->price); strcpy(Node->price,tmp->price); a = atoi(u_head->price); b = atoi(tmp->price); c = a+b; sprintf(buf,"%d",c); strcpy(Node->aggregate,buf); printf("you need pay for %d rmb ",b); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"you need pay for %d rmb ",b); send(connfd,sendbuf,strlen(sendbuf),0); list_add_tail(&(Node->list),&(u_head->list)); } printf("buy successful "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"buy successful "); send(connfd,sendbuf,strlen(sendbuf),0); } } return 0; } /*普通用户退票,输入登陆用户的地址和航班的头*/ int user_ret_fun(struct list_node *u_head,struct list_node *p_head,int connfd) { char number[10]; struct list_head *p = NULL; struct list_node *tmp = NULL; struct list_head *q = NULL; struct list_node *obj = NULL; printf("=========================================================================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); printf(" number staddress arraddress date type stime price "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," number staddress arraddress date type stime price "); send(connfd,sendbuf,strlen(sendbuf),0); list_for_each_prev(p,&(p_head->list)) { tmp = list_entry(p,struct list_node,list); if(strcmp(tmp->number,u_head->number) == 0) { tmp = list_entry(p,struct list_node,list); printf(" %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); send(connfd,sendbuf,strlen(sendbuf),0); } else list_for_each_prev(q,&(u_head->list)) { obj = list_entry(q,struct list_node,list); if(strcmp(obj->number,tmp->number) == 0 && strcmp(obj->name,u_head->name) ==0) { printf(" %s %s %s %s %s %s %s ",obj->number,obj->staddress,obj->arraddress,obj->date,obj->type,obj->stime,obj->price); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," %s %s %s %s %s %s %s ",obj->number,obj->staddress,obj->arraddress,obj->date,obj->type,obj->stime,obj->price); send(connfd,sendbuf,strlen(sendbuf),0); } } } printf("=========================================================================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); printf("Please enter the flight you want to return:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"Please enter the flight you want to return: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(number,chars); break; } list_for_each_safe(p,q,&(u_head->list)) { tmp = list_entry(p,struct list_node,list); if(strcmp(tmp->number,number) == 0 && strcmp(tmp->name,u_head->name) == 0) { printf("return you %s rmb ",tmp->price); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"return you %s rmb ",tmp->price); send(connfd,sendbuf,strlen(sendbuf),0); list_del(p); free(tmp); return 0; } } printf("you don't hav fight "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"you don't hav fight "); send(connfd,sendbuf,strlen(sendbuf),0); return -1; } /*普通用户改签,输入登陆用户的地址和航班的头*/ int user_tic_fun(struct list_node *u_head,struct list_node *p_head,int connfd) { int a,b,c,d; char number[10],p_number[10]; struct list_head *p = NULL; struct list_head *q = NULL; struct list_node *tmp = NULL; struct list_node *obj = NULL; char buff[50],buf[10]; bzero(buff,sizeof(buff)); printf("=========================================================================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); printf(" number staddress arraddress date type stime price "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," number staddress arraddress date type stime price "); send(connfd,sendbuf,strlen(sendbuf),0); list_for_each_prev(p,&(p_head->list)) { tmp = list_entry(p,struct list_node,list); if(strcmp(tmp->number,u_head->number) == 0) { printf("%s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); send(connfd,sendbuf,strlen(sendbuf),0); } else list_for_each_prev(q,&(u_head->list)) { obj = list_entry(q,struct list_node,list); if(strcmp(obj->number,tmp->number) == 0 && strcmp(obj->name,u_head->name) == 0) { printf("%s %s %s %s %s %s %s ",obj->number,obj->staddress,obj->arraddress,obj->date,obj->type,obj->stime,obj->price); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," %s %s %s %s %s %s %s ",obj->number,obj->staddress,obj->arraddress,obj->date,obj->type,obj->stime,obj->price); send(connfd,sendbuf,strlen(sendbuf),0); } } } printf("=========================================================================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); printf("Please enter the flight you want to change: "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"Please enter the flight you want to change: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(number,chars); break; } printf("Flights to be rescheduled: "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"Flights to be rescheduled: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(p_number,chars); break; } list_for_each_prev(p,&(u_head->list)) { tmp = list_entry(p,struct list_node,list); if(strcmp(tmp->number,number) == 0 && strcmp(tmp->name,u_head->name) == 0) { list_for_each_prev(q,&(p_head->list)) { obj = list_entry(q,struct list_node,list); if(strcmp(obj->number,p_number) == 0) { strcpy(tmp->number,obj->number); strcpy(tmp->staddress,obj->staddress); strcpy(tmp->arraddress,obj->arraddress); strcpy(tmp->date,obj->date); strcpy(tmp->type,obj->type); strcpy(tmp->stime,obj->stime); a = atoi(tmp->price); strcpy(tmp->price,obj->price); b = atoi(obj->price); c = a - b; d = atoi(tmp->aggregate); d = d + c; sprintf(buf,"%d",d); strcpy(tmp->aggregate,buf); printf("you need pay for %d rmb ",c); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"you need pay for %d rmb ",c); send(connfd,sendbuf,strlen(sendbuf),0); printf("Endorsed to success "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"Endorsed to success "); send(connfd,sendbuf,strlen(sendbuf),0); return 0; } } } } printf("you don't hav fight "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"you don't hav fight "); send(connfd,sendbuf,strlen(sendbuf),0); return -1; } /*普通用户查看所有航班信息*/ int user_show_all_list(struct list_node *p_head,int connfd) { struct list_head *p = NULL; struct list_node *tmp = NULL; printf("=========================================================================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); printf(" number staddress arraddress date type stime price "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," number staddress arraddress date type stime price "); send(connfd,sendbuf,strlen(sendbuf),0); list_for_each_prev(p,&(p_head->list)) { tmp = list_entry(p,struct list_node,list); printf(" %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); send(connfd,sendbuf,strlen(sendbuf),0); } printf("=========================================================================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); return 0; } /*普通用户通过航班号查看航班==========快速查询*/ int user_number_show_list(struct list_node *p_head,char number[10],int connfd) { struct list_head *p = NULL; struct list_node *tmp = NULL; printf("=========================================================================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); printf(" number staddress arraddress date type stime price "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," number staddress arraddress date type stime price "); send(connfd,sendbuf,strlen(sendbuf),0); list_for_each(p,&(p_head->list)) { tmp = list_entry(p,struct list_node,list); if(strcmp(tmp->number,number) == 0) { printf(" %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); send(connfd,sendbuf,strlen(sendbuf),0); } } printf("=========================================================================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); return 0; } /*普通用户时间/日期/机型查询航班查看航班==========条件查询*/ int user_condition_show_list(struct list_node *p_head,int connfd) { char num; char stime[10],date[10],type[10]; struct list_head *p = NULL; struct list_node *tmp = NULL;char buff[50]; bzero(buff,sizeof(buff)); while(1) { printf("What would you like to inquire through: "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"What would you like to inquire through: "); send(connfd,sendbuf,strlen(sendbuf),0); printf("1.departure time "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"1.departure time "); send(connfd,sendbuf,strlen(sendbuf),0); printf("2.date "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"2.date "); send(connfd,sendbuf,strlen(sendbuf),0); printf("3.type "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"3.type "); send(connfd,sendbuf,strlen(sendbuf),0); printf("4.exit "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"4.exit "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(&num,chars); break; } switch(num) { case 1: printf("please input time:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"please input time: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(stime,chars); break; } list_for_each(p,&(p_head->list)) { tmp = list_entry(p,struct list_node,list); if(strcmp(tmp->stime,stime) == 0) { printf("=========================================================================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); printf(" number staddress arraddress date type stime price "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," number staddress arraddress date type stime price "); send(connfd,sendbuf,strlen(sendbuf),0); printf(" %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); send(connfd,sendbuf,strlen(sendbuf),0); printf("============================================================================ "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); } } break; case 2: printf("please input date:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"please input date: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(date,chars); break; } list_for_each(p,&(p_head->list)) { tmp = list_entry(p,struct list_node,list); if(strcmp(tmp->date,date) == 0) { printf("=========================================================================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); printf(" number staddress arraddress date type stime price "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," number staddress arraddress date type stime price "); send(connfd,sendbuf,strlen(sendbuf),0); printf(" %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); send(connfd,sendbuf,strlen(sendbuf),0); printf("============================================================================ "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); } } break; case 3: printf("please input type:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"please input type: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(type,chars); break; } list_for_each(p,&(p_head->list)) { tmp = list_entry(p,struct list_node,list); if(strcmp(tmp->type,type) == 0) { printf("=========================================================================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); printf(" number staddress arraddress date type stime price "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," number staddress arraddress date type stime price "); send(connfd,sendbuf,strlen(sendbuf),0); printf(" %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf," %s %s %s %s %s %s %s ",tmp->number,tmp->staddress,tmp->arraddress,tmp->date,tmp->type,tmp->stime,tmp->price); send(connfd,sendbuf,strlen(sendbuf),0); printf("============================================================================ "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================================================================== "); send(connfd,sendbuf,strlen(sendbuf),0); } } break; case 4: return 0; break; default: break; } } return -1; } /*释放整条链表*/ int delete_list(struct list_node *_head) { struct list_node *p = NULL; struct list_node *q = NULL; list_for_each_entry_safe(p,q,&(_head->list),list) { list_del(&(p->list)); free(p); } list_del(&(_head->list)); free(_head); return 0; } /*航班管理触摸处理函数*/ int flight_track_fun(int connfd) { char buff[6]; int get; fd_set rset; int maxfd = connfd > STDIN_FILENO ? connfd : STDIN_FILENO; while(1) { FD_ZERO(&rset); FD_SET(connfd,&rset); FD_SET(STDIN_FILENO,&rset); select(maxfd+1,&rset,NULL,NULL,NULL); if(FD_ISSET(STDIN_FILENO,&rset)) { bzero(buff,sizeof(buff)); fgets(buff,sizeof(buff),stdin); get = atoi(buff); return get; } if(connfd != 0) { bzero(buff,sizeof(buff)); if(recv(connfd,buff,sizeof(buff),0)>0) { get = atoi(buff); return get; } } } return 0; } /*子主界面触摸处理函数*/ int sun_main_interface_fun(int connfd) { char buff[6]; int get; fd_set rset; int maxfd = connfd > STDIN_FILENO ? connfd: STDIN_FILENO; while(1) { FD_ZERO(&rset); FD_SET(connfd,&rset); FD_SET(STDIN_FILENO,&rset); select(maxfd+1,&rset,NULL,NULL,NULL); if(FD_ISSET(STDIN_FILENO,&rset)) { bzero(buff,sizeof(buff)); fgets(buff,sizeof(buff),stdin); get = atoi(buff); return get; } if(connfd != 0) { bzero(buff,sizeof(buff)); if(recv(connfd,buff,sizeof(buff),0)>0) { get = atoi(buff); return get; } } } return 0; } /*主界面触摸处理函数*/ int main_interface_fun(int connfd) { char buff[6]; int get; fd_set rset; int maxfd =connfd > STDIN_FILENO ? connfd : STDIN_FILENO; while(1) { FD_ZERO(&rset); FD_SET(connfd,&rset); FD_SET(STDIN_FILENO,&rset); select(maxfd+1,&rset,NULL,NULL,NULL); if(FD_ISSET(STDIN_FILENO,&rset)) { bzero(buff,sizeof(buff)); fgets(buff,sizeof(buff),stdin); get = atoi(buff); return get; } if(connfd != 0) { bzero(buff,sizeof(buff)); if(recv(connfd,buff,sizeof(buff),0)>0) { get = atoi(buff); return get; } } } return 0; } /*管理航班信息,输入航班头*/ int manage_fun(struct list_node *p_head,int connfd) { char num; while(1) { printf("========manage menu======= "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"========manage menu======= "); send(connfd,sendbuf,strlen(sendbuf),0); printf("1.Add flights ");//添加航班信息 bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"1.Add flights "); send(connfd,sendbuf,strlen(sendbuf),0); printf("2.Modify the flight ");//添加航班信息 bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"2.Modify the flight "); send(connfd,sendbuf,strlen(sendbuf),0); printf("3.exit manage menu ");//添加航班信息 bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"3.exit manage menu "); send(connfd,sendbuf,strlen(sendbuf),0); printf("=========================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"=========================== "); send(connfd,sendbuf,strlen(sendbuf),0); printf("Please enter your choice:"); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"Please enter your choice: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(&num,chars); break; } switch(num) { case 1: tail_add_list_plant(p_head,connfd); break; case 2: delete_list_node_number(p_head,connfd); break; case 3: return 0; default: break; } } return -1; } /*主界面---显示登陆界面:*/ int home_screen_fun(int connfd) { printf("========Home Screen========= "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"========Home Screen========= "); send(connfd,sendbuf,strlen(sendbuf),0); printf("1.register ");//用户注册,需调用tail_add_list_user(struct list_node *u_head) bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"1.register "); send(connfd,sendbuf,strlen(sendbuf),0); printf("2.login ");//用户登陆,需调用menu_fun() bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"2.login "); send(connfd,sendbuf,strlen(sendbuf),0); printf("3.manage ");//管理航班,添加航班或删除航班,需调用manage_fun(struct list_node *p_head) bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"3.manage "); send(connfd,sendbuf,strlen(sendbuf),0); printf("4.exit ");//退出程序 bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"4.exit "); send(connfd,sendbuf,strlen(sendbuf),0); printf("============================ "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"============================ "); send(connfd,sendbuf,strlen(sendbuf),0); } /*主菜单---显示登陆成功:*/ int menu_fun(int connfd) { printf("========MENU========= "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"========MENU========= "); send(connfd,sendbuf,strlen(sendbuf),0); printf("1.Show all flights ");//查询所有航班 bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"1.Show all flights "); send(connfd,sendbuf,strlen(sendbuf),0); printf("2.Criteria Query ");//条件查询 bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"2.Criteria Query "); send(connfd,sendbuf,strlen(sendbuf),0); printf("3.fasttips ");//快速查询 bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"3.fasttips "); send(connfd,sendbuf,strlen(sendbuf),0); printf("4.buy ticket ");//购票 bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"4.buy ticket "); send(connfd,sendbuf,strlen(sendbuf),0); printf("5.ticket changing ");//改签 bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"5.ticket changing "); send(connfd,sendbuf,strlen(sendbuf),0); printf("6.dishonoured cheque ");//退票 bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"6.dishonoured cheque "); send(connfd,sendbuf,strlen(sendbuf),0); printf("7.exit menu ");//退出登陆 bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"7.exit menu "); send(connfd,sendbuf,strlen(sendbuf),0); printf("===================== "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"============================ "); send(connfd,sendbuf,strlen(sendbuf),0); } /*管理航班子菜单*/ int manage_fun_su(struct list_node *p_head,int connfd) { int ret; while(1) { ret = flight_track_fun(connfd); switch(ret) { case 1: tail_add_list_plant(p_head,connfd); break; case 2: delete_list_node_number(p_head,connfd); break; case 3: return 1; break; default: break; } } return 0; } /*用户登陆子函数*/ int usre_landing_fun(struct list_node *u_head,struct list_node *p_head,int connfd) { int touch; char num[10]; while(1) { menu_fun(connfd);//crt显示菜单 touch = sun_main_interface_fun(connfd); switch(touch) { case 1://1、查询所有航班 user_show_all_list(p_head,connfd); break; case 2://2、条件查询 user_condition_show_list(p_head,connfd); break; case 3://3、快速查询 printf("please input you need inquire number: "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"please input you need inquire number: "); send(connfd,sendbuf,strlen(sendbuf),0); while(1) if(char_input(connfd) == 1) { strcpy(num,chars); break; } user_number_show_list(p_head,num,connfd); break; case 4://4、购票 user_buy_fun(u_head,p_head,connfd); break; case 5://5、改签 user_tic_fun(u_head,p_head,connfd); break; case 6://6、退票 user_ret_fun(u_head,p_head,connfd); break; case 7://7、退出登陆 return 1; break; default: break; } } return 0; } /*从文件中读取航班信息*/ int date_reading_fun(struct list_node *p_head,int connfd) { char name[10],passwd[10]; //1. 打开目录 DIR *dp = opendir("./date"); if(dp == NULL) { printf("opendir error! "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"opendir error! "); send(connfd,sendbuf,strlen(sendbuf),0); } //2. 切换到目录下 chdir("./date"); //3. 读取目录中每一项 struct dirent *ep = NULL; while(1) { ep = readdir(dp); if(ep == NULL) //读取完毕 break; if(ep->d_name[0] == '.') continue; char str[50] = {0}; FILE *fp = fopen(ep->d_name,"r"); fread(str,10,5,fp); //printf("%s ",str); char seps[] = ","; struct list_node *Node = NULL; Node = (struct list_node *)malloc(sizeof(struct list_node)); if(Node == NULL) { printf("malloc Node error! "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"malloc Node error! "); send(connfd,sendbuf,strlen(sendbuf),0); } strcpy(Node->name,"admin"); strcpy(Node->passwd,"admin123"); char *tmp; tmp = strtok(str,seps); strcpy(Node->number,tmp); tmp = strtok(NULL,seps); strcpy(Node->staddress,tmp); tmp = strtok(NULL,seps); strcpy(Node->arraddress,tmp); tmp = strtok(NULL,seps); strcpy(Node->date,tmp); tmp = strtok(NULL,seps); strcpy(Node->type,tmp); tmp = strtok(NULL,seps); strcpy(Node->stime,tmp); tmp = strtok(NULL,seps); strcpy(Node->price,tmp); fclose(fp); list_add_tail(&(Node->list),&(p_head->list)); } chdir("../");//切换回上一级目录 //4. 关闭目录 closedir(dp); return 0; } /*从文件中读取用户注册信息*/ int register_reading_fun(struct list_node *u_head,int connfd) { char name[10],passwd[10]; //1. 打开目录 DIR *dp = opendir("./register"); if(dp == NULL) { printf("opendir error! "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"opendir error! "); send(connfd,sendbuf,strlen(sendbuf),0); } //2. 切换到目录下 chdir("./register"); //3. 读取目录中每一项 struct dirent *ep = NULL; while(1) { ep = readdir(dp); if(ep == NULL) //读取完毕 break; if(ep->d_name[0] == '.') continue; char str[50] = {0}; FILE *fp = fopen(ep->d_name,"r"); fread(str,10,5,fp); //printf("%s ",str);// name,passwd char seps[] = ","; //分隔的字符是什么 struct list_node *Node = NULL; Node = (struct list_node *)malloc(sizeof(struct list_node)); if(Node == NULL) { printf("malloc Node error! "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"malloc Node error! "); send(connfd,sendbuf,strlen(sendbuf),0); } char *tmp; tmp = strtok(str,seps); strcpy(Node->name,tmp); tmp = strtok(NULL,seps); strcpy(Node->passwd,tmp); fclose(fp); list_add_tail(&(Node->list),&(u_head->list)); } chdir("../");//切换回上一级目录 //4. 关闭目录 closedir(dp); return 0; } /*从文件中读取用户购票信息*/ int date_login_fun(struct list_node *u_head,int connfd) { char name[10],passwd[10]; //1. 打开目录 DIR *dp = opendir("./user"); if(dp == NULL) { printf("opendir error! "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"opendir error! "); send(connfd,sendbuf,strlen(sendbuf),0); } //2. 切换到目录下 chdir("./user"); //3. 读取目录中每一项 struct dirent *ep = NULL; while(1) { ep = readdir(dp); if(ep == NULL) //读取完毕 break; if(ep->d_name[0] == '.') continue; char str[500] = {0}; FILE *fp = fopen(ep->d_name,"r"); fread(str,100,5,fp); //printf("%s ",str); char seps[] = ","; struct list_node *Node = NULL; Node = (struct list_node *)malloc(sizeof(struct list_node)); if(Node == NULL) { printf("malloc Node error! "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"malloc Node error! "); send(connfd,sendbuf,strlen(sendbuf),0); } char *tmp; tmp = strtok(str,seps); strcpy(Node->name,tmp); tmp = strtok(NULL,seps); strcpy(Node->passwd,tmp); tmp = strtok(NULL,seps); strcpy(Node->number,tmp); tmp = strtok(NULL,seps); strcpy(Node->staddress,tmp); tmp = strtok(NULL,seps); strcpy(Node->arraddress,tmp); tmp = strtok(NULL,seps); strcpy(Node->date,tmp); tmp = strtok(NULL,seps); strcpy(Node->type,tmp); tmp = strtok(NULL,seps); strcpy(Node->stime,tmp); tmp = strtok(NULL,seps); strcpy(Node->price,tmp); tmp = strtok(NULL,seps); strcpy(Node->aggregate,tmp); fclose(fp); list_add_tail(&(Node->list),&(u_head->list)); } chdir("../");//切换回上一级目录 //4. 关闭目录 closedir(dp); return 0; } /*存储所有购票信息*/ int store_all_ticket(struct list_node *u_head,int connfd) { char buff[500],nm[10]; char name[10],passwd[10],number[10],staddress[10],arraddress[10],date[10],type[10],stime[10],price[10],aggregate[10]; struct list_head *p = NULL; struct list_node *tmp = NULL; //1. 打开目录 DIR *dp = opendir("./user"); if(dp == NULL) { printf("opendir error! "); bzero(sendbuf,sizeof(sendbuf)); sprintf(sendbuf,"opendir error! "); send(connfd,sendbuf,strlen(sendbuf),0); } //2. 切换到目录下 chdir("./user"); bzero(nm,sizeof(nm)); sprintf(nm,"rm *.txt"); system(nm); bzero(buff,sizeof(buff)); bzero(nm,sizeof(nm)); list_for_each(p,&(u_head->list)) { tmp = list_entry(p,struct list_node,list); if (atoi(tmp->price) != 0) { sprintf(nm,"%s %s.txt",tmp->name,tmp->number); FILE *fp = fopen(nm,"w+"); strcpy(name,tmp->name); strcpy(passwd,tmp->passwd); strcpy(number,tmp->number); strcpy(staddress,tmp->staddress); strcpy(arraddress,tmp->arraddress); strcpy(date,tmp->date); strcpy(type,tmp->type); strcpy(stime,tmp->stime); strcpy(price,tmp->price); strcpy(aggregate,tmp->aggregate); sprintf(buff,"%s,%s,%s,%s,%s,%s,%s,%s,%s,%s",tmp->name,passwd,number,staddress,arraddress,date,type,stime,price,aggregate); fwrite(buff,50,1,fp); fclose(fp); } } chdir("../"); closedir(dp); return 0; } /*退出程序*/ int exit_fun(struct list_node *p_head,struct list_node *u_head,int connfd) { /*保存用户的购票信息*/ store_all_ticket(u_head,connfd); /*释放链表*/ delete_list(u_head); delete_list(p_head); return 0; } //子线程处理函数 void * fun(void *arg) { int connfd; pthread_t tid; //获得连接的客户端已连接套接字、本线程的tid connfd = *(int *)arg; tid = pthread_self(); /*初始化链表*/ struct list_node *p_head = NULL; struct list_node *u_head = NULL; u_head = init_list_head(u_head,connfd); p_head = init_list_head(p_head,connfd); date_reading_fun(p_head,connfd); date_login_fun(u_head,connfd); register_reading_fun(u_head,connfd); /*定义变量*/ int ret;//用于判定用户选择 struct list_node *u_ret;//普通用户登陆,接收user_name_show_list返回值 sleep(3);//等待3秒 while(1) { home_screen_fun(connfd);//crt显示主界面 ret = main_interface_fun(connfd); switch(ret) { case 1 ://用户注册 tail_add_list_user(u_head,connfd); break; case 2 ://用户登陆 u_ret = user_name_show_list(u_head,connfd); if(u_ret == NULL) break; usre_landing_fun(u_ret,p_head,connfd);//用户登陆子菜单 break; case 3 ://管理航班 manage_fun_su(p_head,connfd); break; case 4 ://退出程序 exit_fun(p_head,u_head,connfd);//退出程序 sleep(1); break; default: break; } } //删除该线程对应的链表节点 delete_list_node_num_ip(head,tid); //关闭连接套接字 close(connfd); //线程退出 pthread_exit(NULL); } int main(int argc, char const *argv[]) { pthread_t tid; //初始化链表 head = init_list_head_ip(head); //创建未连接套接字 int sockfd; sockfd = socket(AF_INET,SOCK_STREAM,0); printf("socket:%d ",sockfd); //绑定IP地址,端口号等到未连接的套接字中 struct sockaddr_in srvaddr; socklen_t len = sizeof(srvaddr); bzero(&srvaddr,len); srvaddr.sin_family = AF_INET; //协议 srvaddr.sin_port = htons(atoi(argv[1]));//端口号 srvaddr.sin_addr.s_addr = htonl(INADDR_ANY);//服务器ip bind(sockfd,(struct sockaddr *)&srvaddr,len); //设置监听套接字 listen(sockfd,5); //等待连接 struct sockaddr_in cliaddr; int connfd; while(1) { //等待连接,连接上就创建线程并将connfd传递给子线程,信息记入链表 connfd = accept(sockfd,(struct sockaddr *)&cliaddr,&len); pthread_create(&tid,NULL,fun,(void *)&connfd); add_list_node_ip(head,connfd,(char *)inet_ntoa(cliaddr.sin_addr),tid); printf("============================ "); printf("connfd:%d ",connfd); printf("new connection:%s ",(char *)inet_ntoa(cliaddr.sin_addr)); printf("tid:%d ",(int)tid); printf("============================ "); continue; } //接合最后一个线程 pthread_join(tid,NULL); //删除整条链表 delete_list_ip(head); //关闭未来连接套接字 close(sockfd); return 0; }
head
#ifndef _HEAD_H_ #define _HEAD_H_ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/mman.h> #include <linux/input.h> #include <dirent.h> #include <sys/wait.h> #include <signal.h> #include <sys/ipc.h> #include <sys/msg.h> #include <sys/sem.h> #include <pthread.h> #include <semaphore.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/select.h> #include <sys/time.h> //#include "kernel_list.h" /* This file is from Linux Kernel (include/linux/list.h) * and modified by simply removing hardware prefetching of list items. * Here by copyright, credits attributed to wherever they belong. * Kulesh Shanmugasundaram (kulesh [squiggly] isis.poly.edu) */ /* * Simple doubly linked list implementation. * * Some of the internal functions (“__xxx”) are useful when * manipulating whole lists rather than single entries, as * sometimes we already know the next/prev entries and we can * generate better code by using them directly rather than * using the generic single-entry routines. */ /** * container_of - cast a member of a structure out to the containing structure * * @ptr: the pointer to the member. * @type: the type of the container struct this is embedded in. * @member: the name of the member within the struct. * */ #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) #define container_of(ptr, type, member) ({ const typeof( ((type *)0)->member ) *__mptr = (ptr); (type *)( (char *)__mptr - offsetof(type,member) );}) /* * These are non-NULL pointers that will result in page faults * under normal circumstances, used to verify that nobody uses * non-initialized list entries. */ #define LIST_POISON1 ((void *) 0x00100100) #define LIST_POISON2 ((void *) 0x00200) struct list_head { struct list_head *next, *prev; }; #define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) #define INIT_LIST_HEAD(ptr) do { (ptr)->next = (ptr); (ptr)->prev = (ptr); } while (0) /* * Insert a new entry between two known consecutive entries. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next) { next->prev = new; new->next = next; new->prev = prev; prev->next = new; } /** * list_add – add a new entry * @new: new entry to be added * @head: list head to add it after * * Insert a new entry after the specified head. * This is good for implementing stacks. */ static inline void list_add(struct list_head *new, struct list_head *head) { __list_add(new, head, head->next); } /** * list_add_tail – add a new entry * @new: new entry to be added * @head: list head to add it before * * Insert a new entry before the specified head. * This is useful for implementing queues. */ static inline void list_add_tail(struct list_head *new, struct list_head *head) { __list_add(new, head->prev, head); } /* * Delete a list entry by making the prev/next entries * point to each other. * * This is only for internal list manipulation where we know * the prev/next entries already! */ static inline void __list_del(struct list_head *prev, struct list_head *next) { next->prev = prev; prev->next = next; } /** * list_del – deletes entry from list. * @entry: the element to delete from the list. * Note: list_empty on entry does not return true after this, the entry is in an undefined state. */ static inline void list_del(struct list_head *entry) { __list_del(entry->prev, entry->next); entry->next = (void *) 0; entry->prev = (void *) 0; } /** * list_del_init – deletes entry from list and reinitialize it. * @entry: the element to delete from the list. */ static inline void list_del_init(struct list_head *entry) { __list_del(entry->prev, entry->next); INIT_LIST_HEAD(entry); } /** * list_move – delete from one list and add as another’s head * @list: the entry to move * @head: the head that will precede our entry */ static inline void list_move(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add(list, head); } /** * list_move_tail – delete from one list and add as another’s tail * @list: the entry to move * @head: the head that will follow our entry */ static inline void list_move_tail(struct list_head *list, struct list_head *head) { __list_del(list->prev, list->next); list_add_tail(list, head); } /** * list_empty – tests whether a list is empty * @head: the list to test. */ static inline int list_empty(struct list_head *head) { return head->next == head; } static inline void __list_splice(struct list_head *list, struct list_head *head) { struct list_head *first = list->next; struct list_head *last = list->prev; struct list_head *at = head->next; first->prev = head; head->next = first; last->next = at; at->prev = last; } /** * list_splice – join two lists * @list: the new list to add. * @head: the place to add it in the first list. */ static inline void list_splice(struct list_head *list, struct list_head *head) { if (!list_empty(list)) __list_splice(list, head); } /** * list_splice_init – join two lists and reinitialise the emptied list. * @list: the new list to add. * @head: the place to add it in the first list. * * The list at @list is reinitialised */ static inline void list_splice_init(struct list_head *list, struct list_head *head) { if (!list_empty(list)) { __list_splice(list, head); INIT_LIST_HEAD(list); } } /** * list_entry – get the struct for this entry * @ptr: the &struct list_head pointer. * @type: the type of the struct this is embedded in. * @member: the name of the list_struct within the struct. */ #define list_entry(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) /** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop counter. * @head: the head for your list. */ #define list_for_each(pos, head) for (pos = (head)->next; pos != (head); pos = pos->next) /** * list_for_each_prev - iterate over a list backwards * @pos: the &struct list_head to use as a loop counter. * @head: the head for your list. */ #define list_for_each_prev(pos, head) for (pos = (head)->prev; pos != (head); pos = pos->prev) /** * list_for_each_safe - iterate over a list safe against removal of list entry * @pos: the &struct list_head to use as a loop counter. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. */ #define list_for_each_safe(pos, n, head) for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next) /** * list_for_each_entry - iterate over list of given type * @pos: the type * to use as a loop counter. * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry(pos, head, member) for (pos = list_entry((head)->next, typeof(*pos), member); &pos->member != (head); pos = list_entry(pos->member.next, typeof(*pos), member)) /** * list_for_each_entry_safe – iterate over list of given type safe against removal of list entry * @pos: the type * to use as a loop counter. * @n: another type * to use as temporary storage * @head: the head for your list. * @member: the name of the list_struct within the struct. */ #define list_for_each_entry_safe(pos, n, head, member) for (pos = list_entry((head)->next, typeof(*pos), member), n = list_entry(pos->member.next, typeof(*pos), member); &pos->member != (head); pos = n, n = list_entry(n->member.next, typeof(*n), member)) #endif
client
#include "head.h" //任务: 负责接收消息。 void *routine(void *arg) //arg = &connfd { int sockfd = *(int *)arg; char buf[1024]; while(1) { bzero(buf,sizeof(buf)); recv(sockfd,buf,sizeof(buf),0); printf("%s",buf); } } int main(int argc,char *argv[]) //./client 192.168.90.2 50001 { //1. 创建一个未连接套接字 int sockfd; sockfd = socket(AF_INET,SOCK_STREAM,0); //2. 直接发起连接 struct sockaddr_in srvaddr; socklen_t len = sizeof(srvaddr); bzero(&srvaddr,len); srvaddr.sin_family = AF_INET;//协议 srvaddr.sin_port = htons(atoi(argv[2])); inet_pton(AF_INET,argv[1],&srvaddr.sin_addr); int ret = connect(sockfd,(struct sockaddr *)&srvaddr,len); if(ret == -1) printf("connect error! "); //2.5 创建线程 pthread_t tid; pthread_create(&tid,NULL,routine,(void *)&sockfd); //3. 不断发送数据给服务器 char buf[1024]; while(1) { bzero(buf,sizeof(buf)); fgets(buf,sizeof(buf),stdin); send(sockfd,buf,strlen(buf),0); if(strncmp(buf,"quit",4) == 0) { break; } } //4. 挂断电话 close(sockfd); return 0; }