void* ScanThread::Entry() { mdnsd d; struct message m; unsigned long int ip; unsigned short int port; struct timeval *tv; fd_set fds; SOCKET s; bool exit = false; d = mdnsd_new(1,1000); if((s = msock()) < 0) { p->err.Printf(_("Can't create socket: %s\n"), strerror(errno)); exit = true; } // register query(w,t) at mdnsd d, submit our address for callback ans() mdnsd_query(d, w.char_str(), t, ans, this); #ifdef __WXGTK__ // this signal is generated when we pop up a file dialog wwith wxGTK // we need to block it here cause it interrupts the select() call sigset_t newsigs; sigset_t oldsigs; sigemptyset(&newsigs); sigemptyset(&oldsigs); sigaddset(&newsigs, SIGRTMIN-1); #endif while(!TestDestroy() && !exit) { tv = mdnsd_sleep(d); long msecs = tv->tv_sec == 0 ? 100 : tv->tv_sec*1000; // so that the while loop beneath gets executed once wxLogDebug(wxT("wxServDisc %p: scanthread waiting for data, timeout %i seconds"), p, tv->tv_sec); // we split the one select() call into several ones every 100ms // to be able to catch TestDestroy()... int datatoread = 0; while(msecs > 0 && !TestDestroy() && !datatoread) { // the select call leaves tv undefined, so re-set tv->tv_sec = 0; tv->tv_usec = 100000; // 100 ms FD_ZERO(&fds); FD_SET(s,&fds); #ifdef __WXGTK__ sigprocmask(SIG_BLOCK, &newsigs, &oldsigs); #endif datatoread = select(s+1,&fds,0,0,tv); // returns 0 if timeout expired #ifdef __WXGTK__ sigprocmask(SIG_SETMASK, &oldsigs, NULL); #endif if(!datatoread) // this is a timeout msecs-=100; if(datatoread == -1) break; } wxLogDebug(wxT("wxServDisc %p: scanthread woke up, reason: incoming data(%i), timeout(%i), error(%i), deletion(%i)"), p, datatoread>0, msecs<=0, datatoread==-1, TestDestroy() ); // receive if(FD_ISSET(s,&fds)) { while(recvm(&m, s, &ip, &port) > 0) mdnsd_in(d, &m, ip, port); } // send while(mdnsd_out(d,&m,&ip,&port)) if(!sendm(&m, s, ip, port)) { exit = true; break; } } mdnsd_shutdown(d); mdnsd_free(d); return NULL; }
int main(int argc, char **argv) { pid_t pid; int i, nb_writers, nb_readers; if(argc != 3) { printf("usage : %s <nb_writers> <nb_readers>\n",argv[0]); return EXIT_FAILURE; } srand(time(NULL)); nb_writers = atoi(argv[1]); nb_readers = atoi(argv[2]); if(pipe(fdw) == -1) { perror("fdw - perror"); return EXIT_FAILURE; } if(pipe(fdr) == -1) { perror("fdr - perror"); return EXIT_FAILURE; } printf("Working...\n"); for(i = 0; i < nb_writers; i++) { pid = fork(); if(pid > 0) { continue; } else if(pid == 0) { close(fdr[0]); close(fdr[1]); close(fdw[0]); sendm(); exit(0); } else { perror("send fork"); return -1; } } for(i = 0; i < nb_readers; i++) { pid = fork(); if(pid > 0) { continue; } else if(pid == 0) { close(fdr[1]); close(fdw[0]); close(fdw[1]); receive(); exit(0); } else { perror("recv fork"); return -1; } } forward(); // Waiting for child processes for(i = 0; i < nb_writers; i++){ waitpid(-1,NULL,0); } for(i = 0; i < nb_readers; i++){ waitpid(-1,NULL,0); } printf("End of program\n"); close(fdr[1]); close(fdr[0]); close(fdw[0]); close(fdw[1]); exit(EXIT_SUCCESS); }
int work(int choice,int clientfd){ int check=-1; FILE *fp; switch(choice){ case 1:{ //當choice為1 則為創建檔案 char create[80] ="Create file:Please input name of the file:"; sendm(clientfd,create,sizeof(create)); //傳送創建檔案的訊息 recv(clientfd,create,sizeof(create),0); //接受client輸入要創建的檔案名 printf("Client create file:%s\n",create); fp = fopen(create,"w"); //創建檔案 if(fp){ strcpy(create,"Create file success!"); //成功 則傳送創建城東的訊息 sendm(clientfd,create,sizeof(create)); } else{ strcpy(create,"Create file fail!"); //失敗 則傳送創建失敗的訊息 sendm(clientfd,create,sizeof(create)); } fclose(fp); break; } case 2:{ //當choice為2 則是編輯檔案 char edit[200]= "Edit file:please input name of the file:"; sendm(clientfd,edit,sizeof(edit)); recv(clientfd,edit,sizeof(edit),0); //接受client輸入要編輯的檔案名 printf("Client open file:%s\n",edit); fp = fopen(edit,"a+"); //以寫入模式 開啟檔案 bzero(edit,sizeof(edit)); strcpy(edit,"Please input words(input :end to quit):"); //傳送訊息 告知使用者可以輸入要填入檔案的訊息 輸入:end時結束編輯 sendm(clientfd,edit,sizeof(edit)); while(1){ //無窮回圈 接收使用者輸入的訊息 recv(clientfd,edit,sizeof(edit),0); if(!strcmp(edit,":end")){ //如果輸入的訊息 為:end則跳出回圈 printf("Edit file done!\n"); break; } fprintf(fp,"%s\n",edit); //如果是一般的輸入 則將文字寫入編輯的文字檔 bzero(edit,sizeof(edit)); } fclose(fp); //關閉檔案 break; } case 3:{ //當choice為3 則是刪除檔案 char removed[50] = "Delete file:Please input name of the file:"; sendm(clientfd,removed,sizeof(removed)); recv(clientfd,removed,sizeof(removed),0); //接受client輸入要刪除的檔案名 if(remove(removed)==0){ //刪除成功remove會回傳0 strcpy(removed,"Remove success!"); //傳送刪除成功訊息 sendm(clientfd,removed,sizeof(removed)); } else{ strcpy(removed,"Remove fail!"); //失敗則傳送刪除失敗的訊息 sendm(clientfd,removed,sizeof(removed)); } break; } case 4:{ //當choice為4 則是列出目錄下的檔案 char list[30] = "Document list:\n"; DIR* dir; struct dirent* ptr; dir = opendir("."); sendm(clientfd,list,sizeof(list)); while((ptr =readdir(dir)) != NULL){ //將目錄下的檔案名稱一個一個傳送給client strcpy(list,ptr->d_name); send(clientfd,list,sizeof(list),0); } close(dir); strcpy(list,"-end"); //傳送完所有檔案名稱則傳送-end sendm(clientfd,list,sizeof(list)); break; } case 5:{ //當choice為5 則是列出目錄下的檔案 char down[60]="Download:Please input the file name"; sendm(clientfd,down,sizeof(down)); recv(clientfd,down,sizeof(down),0); //接收使用者輸入要下載的檔案名稱 fp =fopen(down,"r"); //嘗試開啟檔案 檢查檔案是否存在 if (fp == NULL){ printf("Can not find the file:%s\n",down); } else{ printf("Client download file:%s\n",down); bzero(down,sizeof(down)); while(fgets(down,50,fp)!=NULL){ //開始一行一行讀取server端檔案的內容 並傳送給client sendm(clientfd,down,sizeof(down)); bzero(down,sizeof(down)); } strcpy(down,"done"); //傳送完所有內容 則傳送done sendm(clientfd,down,sizeof(down)); printf("End download\n"); } fclose(fp); break; } case 6:{ //當choice為6 則是離開server char quit[30]="Are you sure to exit?(Y/N)"; sendm(clientfd,quit,sizeof(quit)); //詢問client是否要離開 recv(clientfd,quit, sizeof(quit),0); if(*quit == 'y'|| *quit =='Y'){ //若用戶回傳y 則代表確定離開 printf("Disconnected!\n"); strcpy(quit,"See you!"); sendm(clientfd,quit,sizeof(quit)); close(clientfd); //結束傳輸 return -1; } break; } default: { //如果都不是現有的指令 則回傳錯誤 char err[15]="No command!"; sendm(clientfd,err,sizeof(err)); } } return 1; }