Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 16 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
16
Dung lượng
103,5 KB
Nội dung
Bài tập lớn môn Hệ điều hành Linux Sinh viên thực hiện: Lớp: I Đề tài Xây dựng chơng trình, chơng trình đóng vai trò Server chơng trình lại Client Chơng trình Client gửi tên file đến cho Server yêu cầu Server gửi cho nội dung file II Phơng án giải Xem xét chế giao tiếp nh Pipe, Queue giao tiếp tuần tự, để xây dựng giao thức cho hai tiến trình giao tiếp truyền thông với phức tạp Nếu sử dụng chế giao tiếp vùng nhớ chung việc tạo giao thức cho hai tiến trình đơn giản cách khai báo cờ trạng thái hai tiến trình vùng nhớ chung Khi giao tiếp với hai tiến trình cần kiểm tra biến trạng thái tơng ứng biết đợc tiến trình phản hồi lại nh Tuy việc xây dựng giao thức dễ dàng so với chế giao tiếp nh Pipe, Queue nhng để trình giao tiếp diễn cách đắn không liệu phải cần đến chế đồng hai tiến trinh truy nhập vào vùng nhớ chung để kiểm tra trạng thái hay lấy liệu từ tiến trình lại III Xây dựng kịch giao tiếp hai tiến trình Quá trình giao tiếp đợc mô tả sơ đồ sau Server Client Đợi Yêu cầu truyền file Kiểm tra yêu cầu Chấp nhận yêu cầu Kiểm tra trạng thái Server Gửi tên file Tìm file Trả lời có (hay không có) file Kiểm tra trạng thái Server Nếu có file trả lời sẵn sàng Kiểm tra Client sẵn sàng Nếu Gửi liệu Nhận liệu báo nhận * * * * Gửi liệu Nhận liệu báo nhận Hết liệu Kết thúc Kết thúc Để xây dựng kịch ta định nghĩa số biến sau vùng nhớ chung: request : cờ báo yêu cầu Client confirm : cờ báo chấp nhận yêu cầu Server filenam : tên file Client cần truyền have_file : cờ báo Server có file Client yêu cầu (1: có;0: ) realy : cờ báo sẵn sàng Client have_data : cờ báo có liệu Server count : kích thớc gói liệu Server gửi cho Client message : thông báo kèm theo cờ data : liệu Ngoài có biến sau nh: hand_file : thẻ file đợc mở để ghi hay đọc sem_set_id : ID Semaphore share_id : ID vùng nhớ chung share_add : Địa vùng nhớ chung IV Cài đặt Server Chơng trình a, Giải thuật Bắt đầu Khởi tạo Bắt tay Thành công n y Truyền file Giải phóng Kết thúc b, Cài đặt int main() { int sem_set_id; // ID cua Semaphore dung de dong bo int share_id; // ID cua Vung nho chung int size_share; // Kich thuoc cua vung nho chung char *share_add; // Dia chi cua vung nho chung int hand_file; // The file int rc; // Lay ket qua thuc hien cua cac ham struct shmid_ds share_desc;// Dung de xoa Semaphore int *request; // Thong bao tu Client yeu cau Server truyen du lieu int *confirm; // Thong bao tu Server tra loi co truyen du lieu hay khong int *have_file;// Thong bao tu Server cho Client biet la co file int *realy;//Thong bao tu Client cho Server biet la da san sang nhan du lieu int *have_data;// Thong bao tu Server cho Client biet la van du lieu int *count; //Do dai cua du lieu duoc truyen tu Server char *filename; //Ten file char *message; //Thong bao kem theo de hien man hinh char *data; //Du lieu size_share = 2000; //Cap phat vung nho kich thuoc la size_share share_id = shmget(100,size_share,IPC_CREAT | 0777); if(share_id == -1) { printf("Loi cap phat vung nho chung."); exit(EXIT_FAILURE); } //Gan dia chi vung nho trung vao khong gian bo nho cua tien trinh share_add = shmat(share_id,NULL,0); if(!share_add) { printf("Loi ket gan vung nho chung."); exit(EXIT_FAILURE); } //Tao semaphore sem_set_id = create_sem(1); //Khoi tao semaphore init_sem(sem_set_id,1); //Tro bien request vao vung du lieu chung printf("1\n"); request = (int*)((void*)share_add); (*request) = 0; //Tro bien confirm vao vung du lieu chung printf("2\n"); confirm = (int*)((void*)share_add + sizeof(int)); (*confirm) = 0; //Tro bien have_file vao vung du lieu chung printf("3\n"); have_file = (int*)((void*)share_add + sizeof(int)*2); (*have_file) = 0; //Tro bien realy vao vung du lieu chung printf("4\n"); realy = (int*)((void*)share_add + sizeof(int)*3); (*realy) = 0; //Tro bien have_data vao vung du lieu chung printf("5\n"); have_data = (int*)((void*)share_add + sizeof(int)*4); (*have_data) = 0; //Tro bien count vao vung du lieu chung count = (int*)((void*)share_add + sizeof(int)*5); (*count) = 0; //Tro bien filename vao vung du lieu chung printf("6\n"); filename = (char*)((void*)share_add + sizeof(int)*6); //Tro bien message vao vung du lieu chung printf("7\n"); message = (char*)((void*)share_add + MAX_FILENAME + sizeof(int)*6); //Tro bien data vao vung du lieu chung printf("8\n"); data = (char*)((void*)share_add + MAX_MESSAGE + MAX_FILENAME + sizeof(int)*6); //Bat tay voi Client hand_file = server_hand_shaking(sem_set_id,request,confirm,message ,filename,hand_file,have_file,realy); if(hand_file > 0) { server_transfer(sem_set_id,message,have_data,data,hand_file, count); close(hand_file); } //Xoa Semaphore remove_sem(sem_set_id); //Go vung nho chung shmdt(share_add); //Giai phong vung nho chung shmctl(share_id,IPC_RMID,&share_desc); printf("Server da ket thuc\n"); exit(EXIT_SUCCESS); } Phần khởi tạo sử dụng hàm th viện để khởi tạo Semaphore, vùng nhớ chung, gắn vùng nhớ chung vào vùng nhớ chơng trình hàm đợc trình bày phần lý thuyết Sau phần khởi tạo phần gán địa chị biến vào vùng nhớ chung Chơng trình đợc chia làm hai phần Phần bắt tay phần truyền file Phần bắt tay đợc cài đặt hàm server_hand_shaking, hàm dùng để thực số giao tiếp ban đầu trớc truyền file nh trả lời chấp nhận, có file Phần truyền file đợc cài đặt hàm server_transfer để truyền file Sau hoàn thành trình truyền file giải phóng đợc khởi tạo Hàm bắt tay với Client a, Giải thuật: Bắt đầu n Request = y Trả lời Confirm = Nhận tên file từ Client y Tên file = exit Have_file = Trả lời file n Kiểm tra file n Có file y Have_file = Trả lời có file hỏi sẵn sàng chưa n Realy = y Trả lại thẻ file cho chương trình Kết thúc b, Cài đặt int server_hand_shaking(int sem_set_id,int *request,int *confirm,char*message ,char *filename,int hand_file,int *have_file,int *realy) { printf("Dang doi yeu cau \n"); //Doi yeu cau tu Client while(!(*request)) { sleep(1); } sem_lock(sem_set_id); //Doi de vao su dung tai nguyen, da vao thi cam cac tien trinh khac su dung tai nguyen printf("1.Client: %s\n",message); *confirm = 1;//Tra loi dong y truyen du lieu strcpy(message,"Dong y truyen."); sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen sleep(1);//Doi Client gui ten file sem_lock(sem_set_id);//Doi de vao su dung tai nguyen, da vao thi cam cac tien trinh khac vao su dung tai nguyen while(1) { printf("2.Client: %s\n",message); if(strcasecmp(filename,"exit")==0)return -1; hand_file = open(filename,O_RDONLY); //Kiem tra su ton tai cua file Cleint yeu cau if(hand_file > ) { strcpy(message,"San sang chua?"); *have_file = 1;//Thong bao cho Client biet la co file, va hoi da san sang chua sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen sleep(2);//Doi tra loi san sang cua Client sem_lock(sem_set_id);//Doi de vao su dung tai nguyen, da vao thi cam cac tien trinh khac vao su dung tai nguyen printf("3.Client: %s\n",message); if(*realy == 0) return -1; sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen break; } else { strcpy(message,"Khong tim thay file"); *have_file = 0;//Thong bao cho Client biet khong co file ma no yeu cau sleep(1); sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen sleep(1);//Doi Client goi ten file khac sem_lock(sem_set_id);//Doi de vao su dung tai nguyen, da vao thi cam cac tien trinh khac vao su dung tai nguyen } } return hand_file; } Hàm hoạt động nh sau: ban đầu lặp liên tục kiểm tra biến request = khoá semaphore vào sử dụng vùng nhớ chung gán giá trị cho biến confirm, mở khoá semaphore cho Client vào kiểm tra biến confirm Lúc Client gửi tên file Server lại vào lấy tên file kiểm tra tồn file đó, sau trả lời Client Hàm truyền liệu a, Giải thuật Bắt đầu n Chưa hết file y Đọc liệu từ file vào biến data, count = sizeof(data) have_data = Nhận hiển thị thông báo từ Client Have_data = Kết thúc b, Cài đặt void server_transfer(int sem_set_id,char *message,int *have_data,char *data,int hand_file,int *count) { sem_lock(sem_set_id);//Doi de vao su dung tai nguyen, da vao thi cam cac tien trinh khac vao su dung tai nguyen while((*count = read(hand_file,data,MAX_DATA))!=0) { *have_data = 1; sleep(1); sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen sleep(1);//Doi thong bao tu Client da nhan duoc du lieu sem_lock(sem_set_id);//Doi de vao su dung tai nguyen, da vao thi cam cac tien trinh khac vao su dung tai nguyen printf("Client: %s\n",message); } *have_data = 0; sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen } Hàm hoạt động liệu đợc gửi hết Trong vòng lặp gửi liệu, sau lần gửi liệu Server phải đợi cho Client nhận đợc liệu gửi tiếp V Cài đặt Client 10 Chơng trình a, Giải thuật Bắt đầu Khởi tạo Bắt tay Thành công n y Truyền file Giải phóng Kết thúc b, Cài đặt Chơng trình Client đợc cài đặt giống với chơng trình Server thay hai hàm server_hand_shaking hàm client_hand_shaking, hàm server_transfer hàm client_transfer Hàm bắt tay với Server 11 a, Giải thuật Băt đầu Gửi yêu cầu Request = Kiểm tra phản hồi từ Server n Confirm = y Gửi tên file tới Server y Tên file = exit n Kiểm tra phản hồi từ Server n Have_file = y realy = Trả thẻ file cho chương trình Kết thúc b, Cài đặt int client_hand_shaking(int sem_set_id,int *request,int *confirm,char *message,char *filename,int hand_file,int *have_file,int *realy) { sem_lock(sem_set_id);//Doi de vao su dung tai nguyen, da vao thi cam cac tien trinh khac vao su dung tai nguyen 12 *request = 1;//Client gui yeu cau can truyen du lieu strcpy(message,"Toi muon truyen file"); sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen sleep(1); sem_lock(sem_set_id);//Doi de vao su dung tai nguyen, da vao thi cam cac tien trinh khac vao su dung tai nguyen printf("1.Server: %s\n",message); if(*confirm==1)//Kiem tra trang thai cua server co dong y truyen du lieu khong { while(1) { //Gui ten file yeu cau server printf(" Ten file can truyen: ");fflush(stdin); fgets(filename,MAX_FILENAME,stdin); //Trong truong hop yeu cau server nhieu lan nhung server khong tim thay file thi danh ten file la "exit" de thoat if(strcasecmp(str_no_return(filename),"exit")==0) { sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen return -1; } strcpy(message,"Toi muon co file "); strcat(message,str_no_return(filename)); sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen sleep(1); sem_lock(sem_set_id);//Doi de vao su dung tai nguyen, da vao thi cam cac tien trinh khac vao su dung tai nguyen //Kiem tra thong bao tra loi cua server la co file dang yeu cau khong printf("2.Server: %s\n",message); if(*have_file==1) { strcpy(message,"Da san sang"); *realy = 1;//Tra loi da san sang cho qua trinh truyen du lieu strcat(filename,"_cp"); hand_file = open(filename,O_WRONLY| O_TRUNC|O_CREAT); break; } sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen 13 sleep(1); sem_lock(sem_set_id);//Doi de vao su dung tai nguyen, da vao thi cam cac tien trinh khac vao su dung tai nguyen } } else return -1; sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen sleep(2); return hand_file; } Hàm nhận liệu a, Giải thuật Bắt đầu n Have_data=1 y Nhậndữ liệu hiển thị thông báo từ Server Ghi liệu vào file với kích thước count, trả lời nhận Kết thúc b, Cài đặt void client_transfer(int sem_set_id,char *message,int *have_data,char *data, int hand_file,int *count) { int i; 14 sem_lock(sem_set_id);//Doi de vao su dung tai nguyen, da vao thi cam cac tien trinh khac vao su dung tai nguyen i = 0; while(*have_data) { i++; write(hand_file,data,*count); printf("Block %d: %d bytes\n",i,*count); sprintf(message,"Da nhan duoc block %d",i); sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen sleep(2); sem_lock(sem_set_id);//Doi de vao su dung tai nguyen, da vao thi cam cac tien trinh khac vao su dung tai nguyen } printf("Het \n"); sem_unlock(sem_set_id);//Tra lai tai nguyen cho he thong va cac tien trinh khac co the vao su dung tai nguyen } Hàm thực việc nhận liệu từ Server trả lời nhận đợc liệu biến have_data = VI Một số ý: Chơng trình gồm có file: server3.c, client3.c, ttcs.h Khi chạy file từ hai terminal khác nhau, cần chạy server3 trớc, client3 sau Mục lục: 15 I Đề tài II Phơng án giải III Xây dựng kịch giao tiếp hai tiến trình IV Cài đặt Server Chơng trình a, Giải thuật b, Cài đặt Hàm bắt tay với Client 3 a, Giải thuật b, Cài đặt Hàm truyền liệu a, Giải thuật b, Cài đặt 9 10 V Cài đặt Client 11 Chơng trình a, Giải thuật b, Cài đặt Hàm bắt tay với Server 11 11 11 12 a, Giải thuật b, Cài đặt Hàm nhận liệu a, Giải thuật b, Cài đặt 12 12 14 14 14 VI Một số ý: 15 Mục lục: 16 16 [...]...1 Chơng trình chính a, Giải thuật Bắt đầu Khởi tạo Bắt tay Thành công n y Truyền file Giải phóng Kết thúc b, Cài đặt Chơng trình chính của Client đợc cài đặt giống với chơng trình chính của Server chỉ thay hai hàm server_hand_shaking bằng hàm client_hand_shaking,