// 客户端的写协程处理过程 static void fiber_writer(user_client* client) { client->set_waiter(); client->set_waiting(true); while (true) { int mtype; // 等待消息通知 client->wait(mtype); // 从本身消息队列中提取消息并发送至本客户端 if (client_flush(client) == false) { printf("%s(%d), user: %s, flush error %s\r\n", __FUNCTION__, __LINE__, client->get_name(), acl::last_serror()); break; } #ifdef USE_CHAN if (mtype == MT_LOGOUT) { printf("%s(%d), user: %s, MT_LOGOUT\r\n", __FUNCTION__, __LINE__, client->get_name()); break; } if (mtype == MT_KICK) { printf("%s(%d), user: %s, MT_KICK\r\n", __FUNCTION__, __LINE__, client->get_name()); client->get_stream().write("You're kicked\r\n"); break; } #else if (client->exiting()) { printf("%s(%d), user: %s exiting\r\n", __FUNCTION__, __LINE__, client->get_name()); break; } #endif } client->set_waiting(false); printf(">>%s(%d), user: %s, logout\r\n", __FUNCTION__, __LINE__, client->get_name()); // 通知该客户端退出 client_logout(client); printf("-------__nwriter: %d-----\r\n", --__nwriter); }
static void fiber_reader(user_client* client) { acl::socket_stream& conn = client->get_stream(); conn.set_rw_timeout(0); if (client_login(client) == false) { client_logout(client); return; } printf("fiber-%d: user: %s login OK\r\n", acl_fiber_self(), client->get_name()); acl::string buf; int max_loop = client->get_max_loop(), i; for (i = 0; i < max_loop; ++i) { if (conn.gets(buf)) { if (i <= 1) printf("fiber-%d: gets->%s\r\n", acl_fiber_self(), buf.c_str()); __total_read++; continue; } printf("%s(%d): user: %s, gets error %s, fiber: %d\r\n", __FUNCTION__, __LINE__, client->get_name(), acl::last_serror(), acl_fiber_self()); break; } printf(">>%s(%d), user: %s, logout, loop: %d\r\n", __FUNCTION__, __LINE__, client->get_name(), i); client_logout(client); }
static void fiber_reader(user_client* client) { acl::socket_stream& conn = client->get_stream(); conn.set_rw_timeout(5); if (client_login(client) == false) { client_logout(client); return; } printf("fiber-%d: user: %s login OK\r\n", acl_fiber_self(), client->get_name()); acl::string buf; const char* to = client->get_to(); acl::string msg; int max_loop = client->get_max_loop(), i = 0, n = 0; for (;;) { msg.format("chat|%s|hello world\r\n", to); if (conn.write(msg) != (int) msg.size()) { printf("fiber-%d: msg(%s) write error %s\r\n", acl_fiber_self(), msg.c_str(), acl::last_serror()); } if (conn.gets(buf)) { if (++i <= 1) printf("fiber-%d: gets->%s\r\n", acl_fiber_self(), buf.c_str()); n++; __total_read++; if (n == max_loop) break; continue; } printf("%s(%d): user: %s, gets error %s, fiber: %d\r\n", __FUNCTION__, __LINE__, client->get_name(), acl::last_serror(), acl_fiber_self()); if (client->existing()) { printf("----existing now----\r\n"); break; } if (errno == ETIMEDOUT) printf("ETIMEDOUT\r\n"); else if (errno == EAGAIN) printf("EAGAIN\r\n"); else { printf("gets error: %d, %s\r\n", errno, acl::last_serror()); break; } } printf(">>%s(%d), user: %s, logout, loop: %d, ngets: %d\r\n", __FUNCTION__, __LINE__, client->get_name(), i, n); client_logout(client); }
/** * Determines the command to be executed by parsing the user input * @param String entered by the user */ void comm_process(char *comm_line){ char *comm_args[257]; //Stores tokenized arguments of the input command char temp[999]; //Create a copy of entered command line value int i=0,j; //Counter unsigned int arguments=0; //Stores no of command line arguments //Set all elements of temp array to '\0' memset((char *)&temp,'\0',sizeof(temp)); //Set all elements of char array to '\0' memset((char *)&comm_args,'\0',sizeof(comm_args)); //Copy input string strcpy(temp,comm_line); //Extract command from the user entered string comm_args[0]=strtok(comm_line," "); //printf("\nDEBUG: comm_args[0] is : %s",comm_args[0]); //Extract arguments while(comm_args[i]){ comm_args[++i]=strtok(NULL," "); //printf("\nDEBUG: comm_args[%D] : %s",i,comm_args[i]); if(i==5 || comm_args[i]==NULL) { arguments=i-1; break; } //vprintf("\nDEBUG: comm_args[%d] is :%s",i,comm_args[i]); } comm_line=temp; //Common commands if (strncmp("AUTHOR",comm_args[0],sizeof("AUTHOR")-1)==0 && arguments==0) { success(comm_args[0]); cse4589_print_and_log("I, alizisha, have read and understood the course academic integrity policy.\n"); end_(comm_args[0]); } else if( strncmp("PORT",comm_args[0],sizeof("PORT")-1)==0 && arguments==0 && isLoggedIn==TRUE) { if(my_port>=0 && my_port<=65536){ success(comm_args[0]); cse4589_print_and_log("PORT:%d\n", my_port); }else{ error_(comm_args[0]); } end_(comm_args[0]); } else if( strncmp("IP",comm_args[0],sizeof("IP")-1)==0 && arguments==0 && isLoggedIn==TRUE) { if(getPublicIP()>=0){ success(comm_args[0]); cse4589_print_and_log("IP:%s\n", my_ip); }else{ error_(comm_args[0]); } end_(comm_args[0]); } else if( strncmp("LIST",comm_args[0],sizeof("LIST")-1)==0 && arguments==0 && isLoggedIn==TRUE) { char *ip_addr=(char *)calloc(INET_ADDRSTRLEN+1,sizeof(char)); char *host_name=(char *)calloc(50,sizeof(char)); int list_id; if(mode==CLIENT) { success(comm_args[0]); for(i=0,list_id=1;i<=3;i++) { if(clients[i].port!=NOT_CONNECTED) { //printf("\nDEBUG: 1"); memset(host_name,'\0',50); memset(ip_addr,'\0',INET_ADDRSTRLEN+1); //printf("\nDEBUG: 2"); //printf("\nIP before ntop is: %d",clients[i].ip); inet_ntop(AF_INET,&(clients[i].ip),ip_addr,INET_ADDRSTRLEN); //printf("\nDEBUG: 3"); get_name(host_name,clients[i].ip); //printf("\nDEBUG: 4"); cse4589_print_and_log("%-5d%-35s%-20s%-8d\n", list_id++, host_name, ip_addr, clients[i].port); //printf("\nDEBUG: 5"); } } }else if(mode==SERVER) { success(comm_args[0]); //memset(host_name,'\0',50); //memset(ip_addr,'\0',INET_ADDRSTRLEN+1); /* for(i=0,j=1;i<=3;i++,j++) printf("\n%d\tIP: %d\tPort: %d",j,client_list[i].nodeinfo.ip,client_list[i].nodeinfo.port); fflush(stdout);*/ for(i=0,list_id=1;i<=3;i++) { if(client_list[i].isOnline==TRUE) { memset(host_name,'\0',50); memset(ip_addr,'\0',INET_ADDRSTRLEN+1); //printf("\nDEBUG: 2"); inet_ntop(AF_INET,&(client_list[i].nodeinfo.ip),ip_addr,INET_ADDRSTRLEN); //printf("\nDEBUG: 3"); get_name(host_name,client_list[i].nodeinfo.ip); //printf("\nDEBUG: 4"); cse4589_print_and_log("%-5d%-35s%-20s%-8d\n", list_id++, host_name, ip_addr, client_list[i].nodeinfo.port); } } /* printf("\nAfter listing!"); for(i=0,j=1;i<=3;i++,j++) printf("\n%d\tIP: %d\tPort: %d",j,client_list[i].nodeinfo.ip,client_list[i].nodeinfo.port); fflush(stdout); */ }else { error_(comm_args[0]); } free(ip_addr); free(host_name); end_(comm_args[0]); } else if( strncmp("EXIT",comm_args[0],sizeof("EXIT")-1)==0 && arguments==0) { //Insert method to logout success(comm_args[0]); end_(comm_args[0]); exit(0); } //Server Commands else if( strncmp("STATISTICS",comm_args[0],sizeof("STATISTICS")-1)==0 && arguments==0 && mode==SERVER) { success(comm_args[0]); serv_stats(); end_(comm_args[0]); } else if( strncmp("BLOCKED",comm_args[0],sizeof("BLOCKED")-1)==0 && arguments==1 && mode==SERVER) { command_blocked(comm_args[1]); end_(comm_args[0]); } //Client Commands else if( strncmp("BLOCK",comm_args[0],sizeof("BLOCK")-1)==0 && arguments==1 && mode==CLIENT && isLoggedIn==TRUE && strncmp("BLOCKED",comm_args[0],sizeof("BLOCKED")-1)!=0) { //printf("\nDEBUG: Extracted IP is : %s",comm_args[1]); //fflush(stdout); if(client_block(comm_args[1])==TRUE) { success(comm_args[0]); }else { error_(comm_args[0]); } end_(comm_args[0]); } else if( strncmp("LOGIN",comm_args[0],sizeof("LOGIN")-1)==0 && arguments==2 && mode==CLIENT &&isLoggedIn==FALSE ) { if(client_login(comm_args[1],atoi(comm_args[2]))==TRUE) { success(comm_args[0]); isLoggedIn=TRUE; isLoggedOut=FALSE; FD_SET(client_sock, &master); //Add client_socket to client's master FD list //FD_SET(client_sock, &read_fds); if(client_sock>fdmax) fdmax=client_sock; //printf("\nDebug: Client_socket successfully added to list!"); //fflush(stdout); }else { error_(comm_args[0]); } end_(comm_args[0]); } else if( strncmp("REFRESH",comm_args[0],sizeof("REFRESH")-1)==0 && arguments==0 && mode==CLIENT && isLoggedIn==TRUE) { int i,list_id; char *ip_addr=(char *)calloc(INET_ADDRSTRLEN+1,sizeof(char)); char *host_name=(char *)calloc(50,sizeof(char)); if(client_refresh()==TRUE) { success(comm_args[0]); for(i=0,list_id=1;i<=3;i++) { if(clients[i].port!=NOT_CONNECTED) { //printf("\nDEBUG: 1"); memset(host_name,'\0',50); memset(ip_addr,'\0',INET_ADDRSTRLEN+1); //printf("\nDEBUG: 2"); //printf("\nIP before ntop is: %d",clients[i].ip); inet_ntop(AF_INET,&(clients[i].ip),ip_addr,INET_ADDRSTRLEN); //printf("\nDEBUG: 3"); get_name(host_name,clients[i].ip); //printf("\nDEBUG: 4"); cse4589_print_and_log("%-5d%-35s%-20s%-8d\n", list_id++, host_name, ip_addr, clients[i].port); //printf("\nDEBUG: 5"); } } } else{ error_(comm_args[0]); } free(ip_addr); free(host_name); end_(comm_args[0]); } else if( strncmp("SEND",comm_args[0],sizeof("SEND")-1)==0 && isLoggedIn==TRUE&& mode==CLIENT && arguments>=2) { char *ip,*msg;//comm_args[1]; strtok(comm_line," "); ip=strtok(NULL," "); msg=strtok(NULL,"\n"); if(send_message_client(ip,msg)==TRUE) { success(comm_args[0]); }else { error_(comm_args[0]); } end_(comm_args[0]); } else if( strncmp("BROADCAST",comm_args[0],sizeof("BROADCAST")-1)==0 && isLoggedIn==TRUE && mode==CLIENT &&arguments>=1) { char *msg; /* Extract message from the entire command */ strtok(comm_line," "); //Separate command string msg=strtok(NULL,"\n"); if(send_broadcast(msg)==TRUE) success(comm_args[0]); else error_(comm_args[0]); end_(comm_args[0]); } else if( strncmp("UNBLOCK",comm_args[0],sizeof("UNBLOCK")-1)==0 && arguments==1 && mode==CLIENT && isLoggedIn==TRUE) { if(client_unblock(comm_args[1])==TRUE) { success(comm_args[0]); }else{ error_(comm_args[0]); } end_(comm_args[0]); } else if( strncmp("LOGOUT",comm_args[0],sizeof("LOGOUT")-1)==0 && arguments==0 && mode==CLIENT && isLoggedIn==TRUE) { if(client_logout()==TRUE) { success(comm_args[0]); isLoggedIn=FALSE; isLoggedOut=TRUE; //Stop listening on client_sock FD_CLR(client_sock, &master); }else { error_(comm_args[0]); } end_(comm_args[0]); } else if( strncmp("SENDFILE",comm_args[0],sizeof("SENDFILE")-1)==0 && arguments==2 && mode==CLIENT && isLoggedIn==TRUE){ }else{ } }
static void fiber_reader(user_client* client) { acl::socket_stream& conn = client->get_stream(); conn.set_rw_timeout(0); client->set_reader(); client->set_reading(true); // 登入服务器 if (client_login(client) == false) { client->set_reading(false); printf("----------client_logout-------\r\n"); // 失败,则退出客户端 client_logout(client); printf("----__nreader: %d-----\r\n", --__nreader); return; } // 登入成功,则创建写协程用来向客户端发送消息 go_stack(STACK_SIZE) [&] { __nwriter++; fiber_writer(client); }; conn.set_rw_timeout(0); bool stop = false; acl::string buf; // 从客户端循环读取消息 while (true) { bool ret = conn.gets(buf); if (ret == false) { printf("%s(%d): user: %s, gets error %s, fiber: %d\r\n", __FUNCTION__, __LINE__, client->get_name(), acl::last_serror(), acl_fiber_self()); // 客户端退出 if (client->exiting()) { printf("----exiting now----\r\n"); break; } if (errno == ETIMEDOUT) { if (conn.write("ping\r\n") == -1) { printf("ping error\r\n"); break; } } else if (errno == EAGAIN) printf("EAGAIN\r\n"); else { printf("gets error: %d, %s\r\n", errno, acl::last_serror()); break; } continue; } if (buf.empty()) continue; // 分析客户端发送的消息,交由不同的处理过程 std::vector<acl::string>& tokens = buf.split2("|"); // 本客户端要求退出 if (tokens[0] == "quit" || tokens[0] == "exit") { conn.write("Bye!\r\n"); break; } // 本客户端发送聊天消息 else if (tokens[0] == "chat") { if (client_chat(client, tokens) == false) break; } // 本客户端踢出其它客户端 else if (tokens[0] == "kick") { if (client_kick(client, tokens) == false) break; } // 要求整个服务进程退出 else if (tokens[0] == "stop") { stop = true; break; } else printf("invalid data: %s, cmd: [%s]\r\n", buf.c_str(), tokens[0].c_str()); } printf(">>%s(%d), user: %s, logout\r\n", __FUNCTION__, __LINE__, client->get_name()); client->set_reading(false); // 退出客户端 client_logout(client); printf("----__nreader: %d-----\r\n", --__nreader); if (stop) { int dumy = 1; // 如果要停止服务,则通知监控协程 __chan_monitor.put(dumy); } }