#include #include #include #include #include #include #include #include #include #include #include struct client_socket { //Do Dodania: //Wiadomosci dla kazdego uzytkownika //sockety do recv dla kazdego uzytkownika? int socket; int socket_recv; struct sockaddr_in accept_adr; struct sockaddr_in recv_adr; char msg[1024]; fd_set Client; fd_set Client2; char Ip[40]; }; int main(void) { //ZMIENNE struct sockaddr_in bind_adr; //Glówny socket adres struct sockaddr_in recv_adr; struct sockaddr_in accept_temp_adr; // struct sockaddr_in pliki_adr; int pliki_socket; int socket_bind; //Główny socket int socket_recv; int accept_recv; int accept_temp; unsigned char buff[1024]; char msg[1024] = "Puste"; char msg_copy[1024]; struct client_socket client[7]; //Tablica Klientów fd_set Socket; //Zbiór jednego deskryptora - głównego socketa fd_set Recv; socklen_t dl = sizeof(struct sockaddr_in); //Wielkość struktury int i; //licznik int j; //licznik struct timeval timeout; //Po ilu sekundach select odpuści timeout.tv_sec = 1; timeout.tv_usec = 0; //ZMIENNE DO WYSYLANIA PLIKOW FILE* plik; long read_plik; long send_plik; long wielkosc; long razem; int pliki_accept; struct stat file_info; char* token1; char* token2; char* token3; char* token4; //INICJALIZACJA: Tablica Klientów for(i=0; i<=4; i++){ client[i].socket = 0; strcpy(client[i].msg,"/EMPTY"); } printf("INICJALIZACJA: Tablica Klientow\n"); //INICJALIZACJA: Socket socket_bind = socket(AF_INET, SOCK_STREAM, 0); if(socket_bind < 0) { printf("Error: Socket\n"); return 1; } printf("INICJALIZACJA: Socket\n"); socket_recv = socket(AF_INET, SOCK_STREAM, 0); if(socket_recv < 0) { printf("Error: Socket_Accept\n"); return 1; } printf("INICJALIZACJA: Socket_Accept\n"); pliki_socket = socket(AF_INET, SOCK_STREAM, 0); if (pliki_socket < 0) { printf("Error: Socket_Pliki\n"); return 1; } //INICJALIZACJA: Adres bind_adr.sin_family = AF_INET; bind_adr.sin_port = htons(44445); bind_adr.sin_addr.s_addr = INADDR_ANY; recv_adr.sin_family = AF_INET; recv_adr.sin_port = htons(44444); recv_adr.sin_addr.s_addr = INADDR_ANY; pliki_adr.sin_family = AF_INET; pliki_adr.sin_port = htons(44446); pliki_adr.sin_addr.s_addr = INADDR_ANY; //INICJALIZACJA: Bind if (bind(socket_bind, (struct sockaddr*) &bind_adr, sizeof(bind_adr)) < 0){ printf("Error: Bind\n"); return 1; } printf("INICJALIZACJA: Bind\n"); if(bind(socket_recv, (struct sockaddr*)&recv_adr, sizeof(recv_adr)) < 0) { printf("Error: Bind Recv\n"); return 1; } if(bind(pliki_socket, (struct sockaddr*)&pliki_adr, sizeof(pliki_adr)) < 0) { printf("Error: Bind Pliki\n"); return 1; } //INICJALIZACJA: Listen if (listen(socket_bind, 10) < 0) { printf("Error: Listen\n"); return 1; } printf("INICJALIZACJA: Listen\n"); if(listen(socket_recv, 10) < 0) { printf("Error: Listen Recv\n"); } if(listen(pliki_socket, 10) < 0) { printf("Error: Listen Pliki \n"); } printf("Zaczynam Nasłuchiwanie...\n"); printf("Bazowy na %s:%d\n", inet_ntoa(recv_adr.sin_addr), ntohs(recv_adr.sin_port)); //DODALEM KUBA //NASŁUCHIWANIE KLIENTÓW while (1) { timeout.tv_sec = 1; timeout.tv_usec = 0; //INICJALIZACJA: Zbiór Deskryptorów FD_ZERO(&Socket); FD_ZERO(&Recv); FD_SET(socket_bind, &Socket); FD_SET(socket_recv, &Recv); //SELECT - Sprawdzanie nowych połączeń //Select sprawdza czy można na socketcie wykonać jakiś accept - sprawdza czy ktoś się chce połączyć if(select(socket_bind+1, &Socket, NULL, NULL, &timeout) > 0) { printf("Wykryto polaczenie\n"); if (FD_ISSET(socket_bind, &Socket)) { //printf("Rozpoczynam accept\n"); //Sprawdzenie na które miejsce w tablicy dopisać nowy gniazdo accept_temp = accept(socket_bind,(struct sockaddr*)&accept_temp_adr, &dl); //Sprawdzamy czy istnieje takie ip już //Jeśli tak to odbierz wiadomość //Porównaj wiadomość i zapisz na odpowiednim miejscu //Jeśli nie to wstaw go w nastepne wolne miejsce i = 0; while(i<=4){ if (client[i].socket == 0){ //printf("%s\n", inet_ntoa(temp_accept_adr.sin_addr)); client[i].socket = accept_temp; client[i].accept_adr = accept_temp_adr; FD_SET(client[i].socket, &client[i].Client); printf("Dodano użytkownika %s na miejscu %i\n", inet_ntoa(client[i].accept_adr.sin_addr), i); strcpy(client[i].Ip, inet_ntoa(client[i].accept_adr.sin_addr)); i++; break; } else { printf("Miejsce %i zajęte\n", i); i++; } } } } //ZBIERANIE WIADOMOSCI //Przejrzymy całą tablicę klientów i z tych połączonych zbierzemy ich wysłane wiadomosci if(select(socket_recv+1, &Recv, NULL, NULL, &timeout) > 0) { printf("Wykryto wiadomosc\n"); accept_recv = accept(socket_recv, (struct sockaddr*)&recv_adr, &dl); memset(msg, 0, 1024); memset(msg_copy, 0, 1024); if(recv(accept_recv, msg, 1024, 0) > 0) { //Sklonuj msg i tokenizuj trzy pierwsze słowa (1.user> 2.Down/upload 3.Sciezka do pliku) printf("Zaczynam Kopiowac\n"); strcpy(msg_copy, msg); printf("Kopia: %s\n", msg_copy); printf("Tok1\n"); token1 = strtok(msg_copy, " "); printf("Tok2\n"); token2 = strtok(NULL, " "); printf("Tok3\n"); token3 = strtok(NULL, " "); printf("Tok4\n"); token4 = strtok(NULL, " "); printf("Wiadomosc od %s: %s\n",inet_ntoa(recv_adr.sin_addr), msg); //porównuj po drugim tokenie if(token2 == NULL) { token2 = "Brak"; } if (strcmp(token2, "/EXIT") == 0) { printf("Odebrano /EXIT\n"); printf("token1:%s\n", token1); printf("token2:%s\n", token2); printf("token3:%s\n", token3); printf("token4:%s\n", token4); i = 0; while(i<=4) { if(strcmp(client[i].Ip, inet_ntoa(recv_adr.sin_addr)) == 0) { printf("Użytkownik %i wyszedł\n", i); close(client[i].socket); client[i].socket = 0; } i++; } } else if (strcmp(token2, "/DOWNLOAD") == 0){ printf("Odebrano /DOWNLOAD\n"); printf("token1:%s\n", token1); printf("token2:%s\n", token2); printf("token3:%s\n", token3); printf("token4:%s\n", token4); if(fork() == 0) { pliki_accept = accept(pliki_socket, (struct sockaddr*)&pliki_adr, &dl); if(token3 != NULL) { if(stat(token3, &file_info) < 0) { printf("Brak informacji o pliku"); wielkosc = 0; wielkosc = htonl(wielkosc); send(pliki_accept, &wielkosc, sizeof(long), 0); } else { wielkosc = (long) file_info.st_size; //wielkosc = htonl((long) file_info.st_size); KUBA memset(msg, 0, 1024); //DODANE KUBA snprintf(msg, 1024, "%li", wielkosc); //DODALEM KUBA send(pliki_accept, &msg, sizeof(long), 0); //KUBA // wielkosc = file_info.st_size; USUNIETE KUBA plik = fopen(token3, "rb"); razem = 0; while(razem < wielkosc) { memset(msg, 0, 1024); read_plik = fread(msg, 1, 1024, plik); send_plik = send(pliki_accept, msg, read_plik, 0); if (read_plik != send_plik) { break; } razem += send_plik; } fclose(plik); } close(pliki_accept); exit(0); } else { printf("Niepoprawna wiadomosc\n"); wielkosc = 0; wielkosc = htonl(wielkosc); send(pliki_accept, &wielkosc, sizeof(long), 0); close(pliki_accept); exit(0); } } } else if (strcmp(token2, "/FILE") == 0) { printf("Odebrano /FILE\n"); printf("token1:%s\n", token1); printf("token2:%s\n", token2); printf("token3:%s\n", token3); printf("token4:%s\n", token4); if(fork() == 0) { pliki_accept = accept(pliki_socket, (struct sockaddr*)&pliki_adr, &dl); if(token3 != NULL && token4 != NULL) { //recv(pliki_socket, &wielkosc, sizeof(long), 0); char *eptr; //KUBA wielkosc = strtol(token4, &eptr, 10); //wielkosc = (long) token4; KUBA if(wielkosc <= 0) { //if(wielkosc = ntohl(wielkosc) <= 0) { KUBA printf("Błąd pobierania\n"); } else { razem = 0; plik = fopen(token3, "wb"); while(razem < wielkosc) { memset(msg, 0, 1024); read_plik = recv(pliki_accept, msg, 1024, 0); //read_plik = recv(pliki_socket, msg, 1024, 0); KUBA if(read_plik < 0) { break; } fwrite(msg, 1, read_plik, plik); razem += read_plik; } fclose(plik); } close(pliki_accept); exit(0); } else { printf("Niepoprawna komenda\n"); close(pliki_accept); exit(0); } } //fork //accept //Sprawdz wielkosc pliku //Odbierz plik //close(pliki_accept) } else { printf("Wysyłanie wiadomosci\n"); printf("token1:%s\n", token1); printf("token2:%s\n", token2); printf("token3:%s\n", token3); printf("token4:%s\n", token4); i = 0; //Sprawdz kto jest podlaczony while(i<=4) { if(client[i].socket != 0) { //Wyslij wiadowmosc send(client[i].socket, msg, 1024, 0); printf("Send wysłany"); } i++; } } } close(accept_recv); } }//while printf("------------------------------------------------Koniec??\n"); }//main